面对这样的一个多核CPU时代, 实现并发编程是刚需. 多进程实现并发编程, 效果是特别理想的.
但是, 多线程编程模型有一个明显的缺点, 就是进程太重了, 效率不高.
创建一个进程, 消耗时间比较多.
销毁一个进程, 消耗时间也比较多.
调度一个进程, 消耗时间也比较多.
这里的时间主要是消耗在申请资源上的. 进程是系统分配资源的基本单位. 这其中, 内存分配就是一个大活, 操作系统内部有一定的数据结构把空闲的内存分块管理好. 当我们去进行申请内存的时候, 系统就会从这样的数据结构中找到一个大小合适的空闲内存, 返回给对应的进程.
虽然通过这里的数据结构可以一定程度上地提高效率, 但是整体来说, 管理的空间比较多, 相比之下还是一个耗时操作.
为了解决上述问题, 就引入了"线程" (Thread)
线程也叫做"轻量级进程"
创建线程,比创建进程,更快;
销毁线程,比销毁进程,更快;
调度线程,比调度进程,更快......
线程不能独立存在,而是要依附于进程.(进程包含线程)进程可以包含一个线程,也可以包含多个线程.
一个进程, 最开始的时候, 至少要有一个线程. 这个线程负责完成执行代码的工作. 也可以根据需要,创建出更多的线程, 从而使当前实现"并发编程"的效果. 每个线程都可以独立地执行一段代码.
前面谈到进程调度,前面的讨论都是基于“一个进程里只有一个线程"的情况.
实际上,一个进程中,是可以有多个线程的. 每个线程,都是可以独立的进行调度的.
每一个线程, 也有状态, 优先级, 上下文,记账信息....
一个进程可能使用一个PCB表示,也可能使用多个PCB表示.
每个PCB对应到一个线程上. 每个线程都有自己的状态,优先级,上下文,记账信息.….. 用来辅助调度.
除此之外,前面谈到的pid,是相同的. 内存指针,文件描述符表,也是共用同一份的.
所以这也是为什么 进程是资源分配的基本单位. 线程是调度执行的基本单位.