Linux中线程的概念及创建应用

来源:互联网 发布:深圳车险理赔数据 编辑:程序博客网 时间:2024/06/17 11:00

一.线程的概念
线程,是程序执行流的最小单元。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机 ; 运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。
每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
二.线程与进程的区别
在Linux下并没有专门为线程设计这么一个概念,也就是说没有真正意义上的线程,它在Linux下是由进程模拟的,可以认为所有的PCB都可以称为轻量级进程(不一定是进程,也可能是线程)。进程是分配系统资源的一个实体,而线程是CPU调度的基本单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。相对来说,多进程相对稳定,多线程相对不稳定。可以认为,进程是分配系统资源的一个实体,而线程是CPU调度的基本单位。
进程具有独立的地址空间,而线程并没有,同一进程内部的线程共享进程的地址空间。
三.多线程相对于多进程的优缺点
1.多线程的优点:
无需跨进程边界;
程序逻辑和控制方式简单;
所有线程可以直接共享内存和变量等;
线程方式消耗的总资源比进程方式好;
2.多线程的缺点:
每个线程与主程序共用地址空间,受限于有限的地址空间;
线程之间的同步和加锁控制比较麻烦;
一个线程的崩溃可能影响到整个程序的稳定性;
到达一定的线程数程度后,即使再增加CPU也无法提高性能;
线程能够提高的总性能有限,而且线程多了之后,线程本身的调度也很麻烦,需要消耗较多的CPU;
3.多进程的优点:
每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;
通过增加CPU,就可以容易扩充性能;
可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系;
每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大;
4.多进程的缺点:
逻辑控制复杂,需要和主程序交互;
需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算;
多进程调度开销比较大;

四.线程所具有的资源
线程共享的进程资源及环境:
1. ⽂文件描述符表
2. 每种信号的处理⽅方式(SIG_IGN、SIG_DFL或者⾃自定义的信号处理函数)
3. 当前⼯工作⽬目录
4. ⽤用户id和组id

每个线程私有一份的资源:
1. 线程id
2. 上下⽂文,包括各种寄存器的值、程序计数器和栈指针
3. 栈空间
4. errno变量
5. 信号屏蔽字
6. 调度优先级

五.线程的创建/等待/终止
我们将要学习的线程库函数是由POSIX标准定义的,称为POSIX thread或者pthread。在Linux 上线程函数位于libpthread共享库中,因此在编译时要加上-lpthread选项。
1.进程的创建函数pthread_create
这里写图片描述
此函数成功返回0,失败返回错误号,实际上pthread中的函数失败的返回值都是返回错误号
2.进程的等待函数pthread_join
这里写图片描述
同样的,成功返回0,失败返回错误号。
3.进程的终止函数pthread_exit
这里写图片描述
实际上,线程的终止有三种方式:
①return可以表示线程终止
②使用pthread_exit表示线程终止
③线程可以调用pthread_cancel被取消,返回值是-1
4.进程的取消函数pthread_cancel
这里写图片描述

相关的测试代码如下:
这里写图片描述

在这里,thread_run函数是线程去执行的函数,而main函数是主线程所执行的函数,下面我们来看线程的三种终止方式的退出结果。

如上图所示,是第一种线程终止的方式,利用pthread_cancel函数取消线程,其测试结果如图:
这里写图片描述
可以看到其返回值ret是-1。

下面看第二种线程终止的方式,利用pthread_exit函数终止线程,其测试代码及测试结果如图:
这里写图片描述
这里写图片描述
可以看到程序最终接受到的返回码就是123,是pthread_exit中的参数值。

最后一种线程终止的方式,就是在函数中直接return返回,其测试代码及测试结果如图:
这里写图片描述
这里写图片描述
可以看到程序最终返回的就是1,就是thread_run函数中return给主函数的值。