点我查看操作系统秘籍连载


并行和并发

现代操作系统允许『并行』运行多个进程,这里使用双引号包围了并行两个字,因为它真正的含义不是并行,而应该是并发。

  • 并行(parallelism),指的是在某一时刻能够同时执行多个进程。由于每核心CPU在某一时刻都只能执行一个进程,所以要同时执行多个进程,必须要使用多核CPU才能达到真正的并行。这里的同时,指的是同一时刻或并列的意思。
  • 并发(concurrency),指的是能够同时处理多个任务。这里的同时,指的不是同一时刻,更像是一种共存的含义。

从含义上可能很难区分并行和并发,但其实举例说明就非常容易理解。

更广泛一点的定义,并发指的是同时有多个任务到达,或者说,站在某个时间点去看,同时有多个任务存放在那里,这些任务都要被处理。但是处理这些任务的方式,可能是一个一个处理的,处理完一个再去处理另一个(当然,也可能是同时处理多个的,这和是否编写了多进程代码有关),最终,这些任务都被处理完。

如图,是以OS调度多个cat进程为例,这里有4个cat进程要运行。

通常,我们会使用并发数的概念,它表示涌进了多少个任务,这个涌进可以是一次性的,也可以是分多次的,只要站在某个时间点或一个规定的时间段去看,有多少个共存的任务需要被处理,这个数量就是那一时间点或那个时间段的并发数,所以并发任务是有到达的先后顺序的。比如向web服务器发起1000个并发请求。

我们也会使用处理并发数的概念,表示在某个时间段内(通常指的是1秒内)毫不停歇地处理了多少并发请求。处理并发数是衡量性能或效率的一个常用指标。

再来看并行。当有多核CPU时,在任何时刻,每核心CPU都可以执行一个进程,所以多核CPU下可以并列同时执行多个进程,这就是真正的并行。

那么操作系统上要同时运行多个程序为例,所有的进程都在等待被调度,这是一种并发现象。假如只有单核CPU,只能先执行一会A进程,再执行一会进程B。如果有双核CPU,那么可以让CPU1执行进程A,CPU2执行进程B,两个CPU同时都处于工作状态。如图,4个cat进程被2个CPU瓜分。

假设有个程序中编写了多进程(假如两个进程)的代码,但是只有单核CPU,那么这两个进程只能以伪并行的方式执行,正如执行一会进程A,再执行一会进程B。这其实比串行的单进程代码效率更低,因为进程切换有开销。但如果有多核CPU,那么这两个进程可以同时被两个CPU拿去执行,这才是真正的并行,效率才会更高。

关于并发和并行,需要理解的东西概括起来就两句话:

  • 并发和并行完全是两个概念。并发描述的是有多个任务等待着要被处理这件事,并行描述的是能同时一次性处理多个任务的能力。
  • 只有多核CPU才能实现真正的并行,才具有真正的高效率,单核CPU处理多进程通过进程切换实现,是伪并行,效率反而会比串行方式更低,因为进程切换会消耗资源和时间。

多进程/多线程和并行/并发的关系

可以以多进程或多线程的方式进行编程,让它们同时执行多个任务。

但多进程或多线程描述的其实是并发而非并行。让人误以为它们是并行的原因,我想是因为分时系统的调度方式。比如当只有单核CPU时,这些多进程和多线程都无法并行执行。只有当多进程或多线程的任务可以运行在多核CPU时,此时的并发才是并行的。