不懂并行和并发?一文彻底搞懂并行和并发的区别

先举例子来理解这2个概念的区别 。
老师让两个同学去办公室谈话 。如果这两同学(进程)是并列跨过办公室门(CPU)的 , 那么就是并行 。如果同学A先进同学B后进入(或者先B后A) , 或者两人并列同时进入 , 但是在办公室外的路人甲(用户)看来 , 同学A和同学B同时都在办公室内 , 这是并发 。

不懂并行和并发?一文彻底搞懂并行和并发的区别

文章插图
 
其实这个例子不合理 , 因为真正的并行是多核CPU下的概念 , 但上面这个简单的例子非常有助于理解 。
如果举例要精确一点 , 那么大概是这样的:进办公室有两个门(两CPU) , 如果两同学分别从不同的门进入 , 不管先后性 , 两者互相独立 , 那么是并行;如果两同学不管以什么方式进入 , 在路人甲看来 , 他两同时都在办公室内 , 就是并发 。
不懂并行和并发?一文彻底搞懂并行和并发的区别

文章插图
 
我不信到现在还不理解并发和并行 。
并发和并行的理论性解释为什么操作系统上可以同时运行多个程序而用户感觉不出来?
这是因为无论是单CPU还是多CPU , 操作系统都营造出了可以同时运行多个程序的假象 。实际的过程操作系统对进程的调度以及CPU的快速上下文切换实现的:每个进程执行一会就先停下来 , 然后CPU切换到下个被操作系统调度到的进程上使之运行 。因为切换的很快 , 使得用户认为操作系统一直在服务自己的程序 。
再来解释并发就容易理解多了 。
并发(concurrent)指的是多个程序可以同时运行的现象 , 更细化的是多进程可以同时运行或者多指令可以同时运行 。但这不是重点 , 在描述并发的时候也不会去扣这种字眼是否精确 , 并发的重点在于它是一种现象 。并发描述的是多进程同时运行的现象 。但实际上 , 对于单核心CPU来说 , 同一时刻只能运行一个进程 。所以 , 这里的"同时运行"表示的不是真的同一时刻有多个进程运行的现象 , 这是并行的概念 , 而是提供一种功能让用户看来多个程序同时运行起来了 , 但实际上这些程序中的进程不是一直霸占CPU的 , 而是执行一会停一会 。
所以 , 并发和并行的区别就很明显了 。它们虽然都说是"多个进程同时运行" , 但是它们的"同时"不是一个概念 。并行的"同时"是同一时刻可以多个进程在运行(处于running) , 并发的"同时"是经过上下文快速切换 , 使得看上去多个进程同时都在运行的现象 , 是一种OS欺骗用户的现象 。
实际上 , 当程序中写下多进程或多线程代码时 , 这意味着的是并发而不是并行 。并发是因为多进程/多线程都是需要去完成的任务 , 不并行是因为并行与否由操作系统的调度器决定 , 可能会让多个进程/线程被调度到同一个CPU核心上 。只不过调度算法会尽量让不同进程/线程使用不同的CPU核心 , 所以在实际使用中几乎总是会并行 , 但却不能以100%的角度去保证会并行 。也就是说 , 并行与否程序员无法控制 , 只能让操作系统决定 。
再次注明 , 并发是一种现象 , 之所以能有这种现象的存在 , 和CPU的多少无关 , 而是和进程调度以及上下文切换有关的 。
理解了概念 , 再来深入扩展下 。
 
串行、并行和并发任务描述
如图:
不懂并行和并发?一文彻底搞懂并行和并发的区别

文章插图
 
任务是将左边的一堆柴全部搬到右边烧掉 , 每个任务包括三个过程:取柴 , 运柴 , 放柴烧火 。
这三个过程分别对应一个函数:
func get { geting }func carry { carrying }func unload { unloading }串行模式
串行表示所有任务都一一按先后顺序进行 。串行意味着必须先装完一车柴才能运送这车柴 , 只有运送到了 , 才能卸下这车柴 , 并且只有完成了这整个三个步骤 , 才能进行下一个步骤 。
和稍后所解释的并行相对比 , 串行是一次只能取得一个任务 , 并执行这个任务 。


推荐阅读