进程、线程、协程的总结
学习 程序员小灰 - 一文讲透 “进程、线程、协程”的笔记记录
进程
程序本身是没有生命周期的,它只是存在磁盘上的一些指令,程序一旦运行就是进程
。
进程是-操作系统 提供的 抽象概念
,是系统进行 资源分配和调度的 基本单位
(出现线程以后,调度的基本单位就是线程),是操作系统结构的基础。程序是指令、数据及其组织形式的描述
,进程是程序的实体
。
当程序需要运行时,OS 将代码和所有静态数据记载到内存和进程的地址空间(每个进程都拥有唯一的地址空间
)中,通过创建和初始化栈(局部变量,函数参数和返回地址)、分配堆内存以及与IO相关的任务;当前期准备工作完成,启动程序,OS 将 CPU 的控制权转移到新创建的进程,进程开始运行。
一个进程至少有五种基本状态:
- 初始态:进程刚被创建,准备其他系统资源
- 就绪态:所有所需资源已准备完成,等待被调度CPU资源
- 运行态:执行状态
- 阻塞态:进程等待某件事情完成
- 终止态:进程结束
CPU资源上进程间的切换,被称为上下文切换(context switch)。涉及到:
- 保存当前进程的上下文
- 恢复新进程的上下文
分配、回收系统资源;
更新PCB
中的信息;
将PCB
放入合适的队列;
进程间的数据共享
系统中的 进程 与其他 进程 共享
CPU和主存资源,为了更好的管理主存,现在系统提供了一种对主存的抽象概念,即为虚拟存储器(VM)。它是一个抽象的概念,它为每一个进程提供了一个假象:即每个进程都在独占地使用主存。
虚拟存储器
主要提供了三个能力:
-
将主存看成是一个存储在磁盘上的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,更
高效地使用主存
-
为每个进程提供了
一致
的地址空间,从而简化了存储器管理 -
保护了每个进程的地址空间不被其他进程破坏(映射)
线程
线程-也是操作系统提供的抽象概念,是程序执行流的最小单元
,是 处理器调度和分派的基本单位
。一个进程可以有一个或多个线程,同一进程中的多个线程将共享
该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈和线程本地存储(如下图所示)。
OS 会为线程分配一个线程控制块TCB(Thread Control Block),将所有用于控制和管理线程的信息记录在线程的控制块中,TCB中通常包括:
- 线程标志符
- 一组寄存器
- 线程运行状态
- 优先级
- 线程专有存储区(堆、栈)
- 信号屏蔽
进程与线程的区别
-
进程是资源的分配和调度的独立单元。进程拥有完整的虚拟地址空间,当发生进程切换时,不同的进程拥有不同的虚拟地址空间。而同一进程的多个线程是可以共享同一地址空间
-
线程是CPU调度的基本单元,一个进程包含若干线程。
-
线程比进程小,基本上不拥有系统资源。线程的创建和销毁所需要的时间比进程小很多
-
由于线程之间能够共享地址空间,因此,需要考虑同步和互斥操作
-
一个线程的意外终止会影响整个进程的正常运行,但是一个进程的意外终止不会影响其他的进程的运行。因此,多进程程序安全性更高。
总之,多进程程序安全性高,进程切换开销大,效率低;多线程程序维护成本高,线程切换开销小,效率高。
协程
协程(Coroutine,又称微线程)是一种 比线程更加轻量级
的存在,协程不是被操作系统内核所管理,而完全是由程序所控制。协程与线程以及进程的关系见下图所示。
-
协程可以比作子程序,但执行过程中,子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。协程之间的切换不需要涉及任何系统调用或任何阻塞调用。
-
协程只在一个线程中执行,子程序之间的切换发生在用户态上,而线程的阻塞状态是由操作系统内核来完成,发生在内核态上,因此协程相比线程节省线程创建和切换的开销。
-
协程中不存在同时写变量冲突,因此,也就不需要用守卫关键区块的同步性原语,比如互斥锁、信号量等,并且不需要来自操作系统的支持。
线程之间是如何进行协作的呢?
最经典的例子是生产者/消费者模式,即若干个生产者线程向队列中系欸如数据,若干个消费者线程从队列中消费数据。