1. 并发与并行
并发和并行是相似的术语,但它们并不是一回事
并发是在 CPU 上同时运行多个任务的能力。任务可以在重叠的时间段内启动、运行和完成。在单个 CPU 的情况下,多个任务在上下文切换的帮助下运行,其中存储进程的状态,以便稍后调用和执行。
并行性是在多个 CPU 内核上同时运行多个任务的能力。
通俗点解释就是,区别就在于是否可以“同时”处理。比如正在用 pad 看电影,这时电话响了,暂停电影然后接电话,挂掉电话之后继续看电影,这就是并发。电影继续播着,一边看电影一边讲电话就是并行。
适用的场景取决于任务是CPU 密集型还是 IO 密集型。
2. 进程与线程
2.1 进程
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
2.2 线程
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
2.3 协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
名称 | 资源 | 调度 | 开销 | CPU |
进程 | 独立空间 | 操作系统 | 高 | n |
线程 | 共享进程空间 | 操作系统 | 低 | 1 |
协程 | 共享进程空间 | 用户 | 几乎没有 | 1 |
3. 多进程与多线程
在 Python 中,多进程是真正意义上的并行,适用于CPU密集型任务。
多线程和协程是并发, 适用于I/O密集型任务。
从上图可以看出多进程可以运行在多个 cpu 上, 由于GIL (Python 并发编程(二) GIL )的存在, python的多线程只能跑在一个 cpu 上,协程是轻量的线程也只能跑在一个 cpu 上。
多线程切换, 依赖于操作系统,操作系统可以随时中断它以开始运行其他线程。这称为抢占式多任务处理,因为操作系统可以抢占您的线程以进行切换。
协程的切换,使用协作多任务处理。任务必须通过宣布何时准备好切换来进行协作。这意味着任务中的代码必须稍作更改才能实现。对于python 来说,协程的切换次数更少。