逻辑控制流
在程序加载到内存并执行的时候(进程),操作系统会通过让它和其他进程分时段占用CPU(CPU slices)让它产生自己独占CPU的假象(同时通过虚拟内存让它产生独占内存的假象)。在CPU在执行一个进程的指令时,被执行的许多指令连接起来(也可以理解为程序计数器PC的变化)就构成了“逻辑控制流”。
逻辑控制流的概念也不局限于进程,它在异常处理程序、线程、Java进程中均有体现。而“并发(concurrency)”和”并行(parallel)“都是对逻辑控制流而言的。
并发
当两个逻辑控制流交替执行的时候,我们就称它们是”并发(concurrency)“的。更确切的说,对于逻辑控制流A、B,如果B被执行晚于A被执行的开始且早于A被执行的结束,那么A和B就是并发的。例如下图:
其中A和B是并发的,因为B的执行晚于A的开始且早于A的结束。但是B和C就不是并发的,因为C的执行并没有早于B的结束。同理A和C是并发的。
注意到并发和cpu的个数或者计算机的个数是没有关系的,只要两个逻辑流满足上面的关系我们就称它们并发。
并行
如果两个逻辑控制流同时(一个cpu时段内)在不同的cpu(多核)或者计算机上被执行,我们就称其为并行。例如下图:
其中A和C、B和D之间就是并行执行的。
注意到并行要求具有多个处理核心。
另外,我在网上看到一组很有意思的漫画,讲解了并发和并行的区别,分享一下(图片来自https://code.google.com/archive/p/rspace/source/concur/source):
假设一只老鼠正在烧书,其中书就代表要被执行的指令,火炉代表cpu,老鼠把书一本本运送并烧掉的过程就构成了逻辑控制流。
现在有两只老鼠(两个逻辑控制流)在烧书,例如下面这个图,由于只有一个火炉,一个老鼠烧书的时候,另外一个就要等着(保存上下文),直到烧完后轮到他烧(上下文切换),即他们烧书是交替进行的,我们就说他们在并发。(多个火炉满足这样的交替关系我们也可以说他们在并发):
当两只老鼠烧书同时进行时,我们就说它们是并行的,例如下面这个例子,由于有两个火炉(多核),烧书本身可以同时发生:
参考:
- 《深入理解计算机系统》第三版
- Rob Pike - ‘Concurrency Is Not Parallelism’