要了解线程,首先就要联系我们学过的进程
1、线程和进程的关系
1.线程是一个轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone。
2.从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三
级页表是相同的。
Unix中如何管理内存,PCB记录地址表,采用三级页面每个页面默认4096字节大小
每四个字节看成一个指针,一个页面1024个指针,指向1024个页面。
三级页面寻址到G(Linux实际用的四级页面寻址)。
其中线程和进程共用页表,即共用地址空间。
3.进程可以蜕变成线程。
典型的UNIX进程可以看成只有一个主控线程(第一个线程):一个进程在某一时刻只能做一件事情。
进程创建若干线程后,地位相同,主控线程退化为普通线程
4.从某种角度来说,线程就是寄存器和栈。
进程的内核栈,把寄存器的值保存到内核栈,保存现场,当从另一线程返回后,恢复处理器现场。
5.在linux下,线程是最小的执行单位;进程是最小的分配资源单位。
图中一个进程下的各线程共用一块内存空间。
而Thread Scheduler去找的最小单位是线程。
这点需要慢慢理解
我们用ps -eLf
LWP即轻量级进程即线程,实际上,CPU在去分别执行的时候并不是以进程pid为单位来分配的,而是以LWP轻量级进程这个编号为单位来分配CPU使用权
可以用ps -Lw pid(进程号)来查看某进程下的各线程
2.线程间共享的资源
1.文件描述符表
2.每种信号的处理方式 //注意这里仅为处理方式
3.当前工作目录
4.用户ID和组ID
5.内存地址空间中 //如malloc后各线程都可以 读取数据Text
data 已初始化的全局变量已初始化的静态变量
bss 未初始化
堆
共享库
这里简单再介绍共享库
共享库怎么被加载到内存?通过mmap
同一个共享库,在各虚拟内存中使用,但在物理内存中只映射一份 。
3.线程间非共享资源
1.线程id
线程ID主要是给调度器用的,线程ID有效范围仅限于本进程
2.处理器现场和栈指针(内核栈)
3.独立的栈空间(用户空间栈)每个线程维护自己独立的栈 ,与内核栈不同,这是用户空间的栈,如局部变量、函数调用传参
4.errno变量
5.信号屏蔽字
6.调度优先级
4.线程优缺点
优点
*提高程序的并发性
*开销小,不用重新分配内存
*通信和共享数据方便而进程间通信需要管道、信号、内存共享,这些开销显然比线程要大
缺点:
*线程不稳定(库函数实现)
*线程调试比较困难(gdb支持不好)
*线程无法使用unix经典事件,例如信号
最后,欢迎在评论区讨论。
博主将不定期更新,欢迎关注和点赞。