参考资料:
【操作系统】进程和线程的区别
面试必备好文丨面试官:进程和线程,我只问这19个问题!
进程与线程
在学习multiprocessing.Queue的时候,需要了解进程和线程。暂时只是浅浅了解一下。
关于下面的“并发编程”,参考自视频:《Python零基础到全栈系列》
进程
进程是”在内存中的可执行程序实例“
,它是一个程序的执行流程,内部保存程序运行所需的资源。
在操作系统中可以有多个进程在运行,可对于CPU来说,同一时刻,一个CPU只能运行一个进程,但在某一时间段内,CPU将这一时间段拆分成更短的时间片,CPU不停的在各个进程间游走
,这就给人一种并行的错觉,像CPU可以同时运行多个进程一样,这就是伪并行。
通过多次执行,一个程序可对应多个进程
,例如在任务管理器可以看多有多个"qq.exe"进程;通过调用关系,一个进程可包括多个程序
。
进程存在三种状态
:
-
运行状态:进程正在处理机上运行时就处在运行状态,该时刻进程时钟占用着CPU;
-
就绪状态:万事俱备,只欠东风,进程已经获得了除处理机之外的一切所需资源,一旦得到处理机就可以运行;就绪态中的进程其实可以运行,但因为其它进程正在占用着CPU而暂时停止运行;
-
等待状态(阻塞状态):进程正在等待某一事件而暂停运行,等待某个资源或者等待输入输出完成。除非某种外部事件发生,否则阻塞态的进程不能运行。
进程挂起就是为了合理且充分的利用系统资源,把一个进程从内存转到外存
。进程在挂起状态时,意味着进程没有占用内存空间,处在挂起状态的进程映射在磁盘上。进程挂起通常有两种状态。
线程
线程是进程当中的一条执行流程,一个进程内可以有多个子执行流程,即线程
。同一进程的不同线程共享资源。进程 = 线程 + 共享资源
。
使用线程的原因是要”并发编程“,例如word打字。交互线程,渲染线程,保存线程需要并行执行。
多进程也可以并行。但是进程间通信复杂,维护进程开销也大。所以引入了
开销较小的多线程编程
,并且并发执行时可以共享相同的地址空间
。
如果多个线程是CPU密集型的,并不能很好的获得更好的性能,但如果多个线程是IO密集型的,线程存在着大量的计算和大量的IO处理,有多个线程允许这些活动彼此重叠进行,从而会加快整体程序的执行速度
。
关于IO密集型和CPU密集型可以参考:IO、CPU密集型分别指什么,有哪些例子,讲透线程池(2/4)
简单来说:IO密集型业务主要在发请求,等待响应,不计算,CPU占用小,这种逻辑适合开多线程,能提高吞吐量
。CPU密集型则主要在本地CPU计算,不适合开多线程。
总结
进程是资源分配单位,线程是CPU调度单位,”并行的最小单位“。
并发编程
并发:看起来像同时运行的。例如能短时间切换执行任务,但是一次只能执行一个任务的。
并行:真正意义上的同时执行。
操作系统发展史
- 单道
-
- 穿孔卡片时代:输入机->主机->输出机
程序需要一个个来,cpu效率低下。
- 穿孔卡片时代:输入机->主机->输出机
-
- 联机批处理系统:输入机->磁带->主机->输出机
提前将程序录入磁带,主机可以依次读取程序,节省了时间。
- 联机批处理系统:输入机->磁带->主机->输出机
-
- 脱机批处理系统:输入机—>卫星机->高速磁带->主机
不用再去机房,远程可以录入程序到卫星机。并且主机直接跟高速磁带(类似内存)交互。这样cpu等待的时间短一些。
- 脱机批处理系统:输入机—>卫星机->高速磁带->主机
这个时代的主要特征是为了
降低cpu的等待时间
。
单核cpu在这个时代的执行是单道(串行),如下图:
- 多道
允许多个应用程序同时进入内存,并且CPU交替执行。当一道程序因为I/O请求暂停运行时。CPU便会立即去运行另一道程序。
多道技术的核心是:cpu切换+保存状态(为了切换时不必重新开始执行)
cpu切换的时候,分两种情况:
1.当一个程序遇到I/O操作时,操作系统会剥夺该程cpu的执行权限。例如python的with open()
。
2.当一个程序长时间占用cpu时,操作系统也会剥夺该程cpu的执行权限。例如某个程序需要cpu执行10分钟,此时又需要执行其他程序
,为了让用户好的体验,这时就需要频繁切换cpu。
多道技术的目的,是为了让单核cpu也能实现并发。
进程调度
程序:存在硬盘上的一堆代码
进程:表示程序正在执行的过程
- 先来先服务调度算法:对长作业友好,短作业不友好
- 短作业优先调度算法:对短作业友好,长作业不友好
- 时间片轮转法+多级反馈队列:越往下,优先级越低,越往下,任务的耗时越长。
建议结合视频"进程调度"看。
进程的三状态图
I/O操作包括:读取/写入文件,发网络请求,input等待用户输入,time.sleep(),print等等
下面是一个示例
同步和异步
用来描述任务的提交方式
- 同步:任务提交之后,原地等待任务的返回结果,等待的过程中不做任何事情
- 异步:任务提交之后,不在原地等待任务的返回结果,而是直接去做其他事情
异步的情况下,结果怎么获取:任务的返回结果会有一个
异步回调机制
自动处理
这里异步提交的任务,通常是一代代码/函数(不是进程)
# 同步的示例代码
import time
def func():