文章目录
PCB(progress control block)与进程分配资源
PCB(progress control block),进程控制块。
当一个可执行程序被系统执行了以后,就变成了一个进程。
那么这个进程中到底有什么东西呢?
系统究竟给这个进程分配了哪些资源?
另外,进程在内存中的存储是怎么样的?
对于一个进程,它在被执行前其实是一个可执行程序。这个程序是被放在磁盘上的,当它要被执行的时候,它先被加载到内存当中,然后再放入到寄存器中,最后再让cpu执行该程序,这个时候一个静态的程序就变成了进程。
那么操作系统是怎么来管理这些进程的呢?
操作系统通过一个双向链表把进程连起来。
但是,对于进程其实它是一个抽象的概念,系统肯定要通过一个东西来描述进程,然后才能管理进程。于是PCB就出来了,操作系统通过PCB来描述进程,于是这个双向链表连接的其实是PCB。
这个PCB是个什么玩意?
它就是一个结构体,用来描述进程,在Linux下,就是task_struct
结构体。
基本概念
LWP
light weight process 轻量级的进程,本质仍是进程(在Linux环境下)
进程
独立地址空间,拥有PCB,最小分配资源单位,可看成是只有一个线程的进程。
线程
也有PCB,但没有独立的地址空间(共享),Linux下最小的执行单位,调度的基本单位。
进程和线程区别
在于是否共享地址空间。
独居(进程)
合租(线程)。
Linux内核线程实现原理
历史
类Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。
进程和线程是都有各自不同的PCB
轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone。
从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的。
进程可以蜕变成线程。
线程可看做寄存器和栈的集合。
在linux下,线程最是小的执行单位;进程是最小的分配资源单位。
察看LWP号:ps –Lf pid 查看指定线程的lwp号。
进程的目录、页表、物理页面各不相同
对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟地址一样,但,页目录、页表、物理页面各不相同。相同的虚拟地址,映射到不同的物理页面内存单元,最终访问不同的物理页面。
三级映射:进程PCB --> 页目录(可看成数组,首地址位于PCB中) --> 页表 --> 物理页面 --> 内存单元
–参考:《Linux内核源代码情景分析》 ----毛德操
线程之间共享同一个页目录
两个线程具有各自独立的PCB,但共享同一个页目录,也就共享同一个页表和物理页面。所以两个PCB共享一个地址空间。
创建进程或者创建线程底层都是调用内核函数clone
实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数clone。
Linux内核是不区分进程和线程的
如果复制对方的地址空间,那么就产出一个“进程”;
如果共享对方的地址空间,就产生一个“线程”。
因此Linux内核是不区分进程和线程的。
只在用户层面上进行区分。所以,线程所有操作函数 pthread_* 是库函数,而非系统调用。
线程共享资源
1.文件描述符表
2.每种信号的处理方式
3.当前工作目录
4.用户ID和组ID
5.内存地址空间 (.text/.data/.bss/heap/共享库)
线程非共享资源
1.线程id
2.处理器现场和栈指针(内核栈)
3.独立的栈空间(用户空间栈)
4.errno变量
5.信号屏蔽字
6.调度优先级
线程优、缺点
优点: 1. 提高程序并发性 2. 开销小 3. 数据通信、共享数据方便
缺点: 1. 库函数,不稳定 2. 调试、编写困难、gdb不支持 3. 对信号支持不好
优点相对突出,缺点均不是硬伤。Linux下由于实现方法导致进程、线程差别不是很大
参考资料
https://blog.csdn.net/qq_22847457/article/details/89371217
https://blog.csdn.net/qq_22847457/article/details/90291051
《Linux内核源代码情景分析》