线程概念优缺点线程函数
Posted 阿龙亡命天涯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程概念优缺点线程函数相关的知识,希望对你有一定的参考价值。
在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体。所以,线程是轻量级的进程(LWP:light weight process),在Linux环境下线程的本质仍是进程。为了让进程完成一定的工作,进程必须至少包含一个线程。
进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源,所以我们也说,进程是CPU分配资源的最小单位。线程存在与进程当中(进程可以认为是线程的容器),线程是操作系统调度执行的最小单位。说通俗点,线程就是干活的。
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
如果说进程是一个资源管家,负责从主人那里要资源的话,那么线程就是干活的苦力。一个管家必须完成一项工作,就需要最少一个苦力,也就是说,一个进程最少包含一个线程,也可以包含多个线程。苦力要干活,就需要依托于管家,所以说一个线程,必须属于某一个进程。
进程有自己的地址空间,线程使用进程的地址空间,也就是说,进程里的资源,线程都是有权访问的,比如说堆啊,栈啊,静态存储区什么的。
进程、线程区别
实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数 clone 。
-
如果复制对方的地址空间,那么就产出一个“进程”;
-
如果共享对方的地址空间,就产生一个“线程”。
Linux内核是不区分进程和线程的, 只在用户层面上进行区分。所以,线程所有操作函数 pthread_* 是库函数,而非系统调用。
==注意:==可以类比学习C++时的深拷贝浅拷贝理解这里的区别,深拷贝就为进程,浅拷贝就为线程
线程共享资源
-
文件描述符表
-
每种信号的处理方式
-
当前工作目录
-
用户ID和组ID
内存地址空间 (.text/.data/.bss/heap/共享库)
线程非共享资源
-
线程id
-
处理器现场和栈指针(内核栈)
-
独立的栈空间(用户空间栈)
-
errno变量
-
信号屏蔽字
-
调度优先级
线程优缺点
优点:
-
提高程序并发性
-
开销小
-
数据通信、共享数据方便
缺点:
-
库函数,不稳定
-
调试、编写困难、gdb不支持
-
对信号支持不好
优点相对突出,缺点均不是硬伤。Linux下由于实现方法导致进程、线程差别不是很大。
线程常规操作
就像每个进程都有一个进程号一样,每个线程也有一个线程号。进程号在整个系统中是唯一的,但线程号不同,线程号只在它所属的进程环境中有效。
进程号用 pid_t 数据类型表示,是一个非负整数。线程号则用 pthread_t 数据类型来表示,Linux 使用无符号长整数表示。
有的系统在实现pthread_t 的时候,用一个结构体来表示,所以在可移植的操作系统实现不能把它做为整数处理。
==注意:==在gcc编译多线程程序时,在末尾需要加上-pthread
线程创建
// 回调函数
void *thread_fun(void * arg)
sleep(1);
int num = *((int *)arg);
printf("int the new thread: num = %d\\n", num);
return NULL;
int main()
pthread_t tid;
int test = 100;
// 返回错误号
int ret = pthread_create(&tid, NULL, thread_fun, (void *)&test);
if (ret != 0)
printf("error number: %d\\n", ret);
// 根据错误号打印错误信息
printf("error information: %s\\n", strerror(ret));
while (1);
return 0;
线程共享数据段、堆、代码段、BSS
线程资源回收
以上是关于线程概念优缺点线程函数的主要内容,如果未能解决你的问题,请参考以下文章