欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

理解并发和并行的区别

程序员文章站 2022-03-28 21:29:16
任务描述 如图: 任务是将左边的一堆柴全部搬到右边烧掉,每个任务包括三个过程:取柴,运柴,放柴烧火。 这三个过程分别对应一个函数: 串行模式 串行表示所有任务都一一按先后顺序进行。串行意味着必须先装完一车柴才能运送这车柴,只有运送到了,才能卸下这车柴,并且只有完成了这整个三个步骤,才能进行下一个步骤 ......

任务描述

如图:

理解并发和并行的区别

任务是将左边的一堆柴全部搬到右边烧掉,每个任务包括三个过程:取柴,运柴,放柴烧火。

这三个过程分别对应一个函数:

func get { geting }
func carry { carrying }
func unload { unloading }

理解并发和并行的区别

串行模式

串行表示所有任务都一一按先后顺序进行。串行意味着必须先装完一车柴才能运送这车柴,只有运送到了,才能卸下这车柴,并且只有完成了这整个三个步骤,才能进行下一个步骤

和稍后所解释的并行相对比,串行是一次只能取得一个任务,并执行这个任务

假设这堆柴需要运送4次才能运完,那么当写下的代码类似于下面这种时,那么就是串行非并发的模式:

for(i=0;i<4;i++){
    get()
    carry()
    unload()
}

或者,将三个过程的代码全部集中到一个函数中也是如此:

func task {
    geting
    carrying
    unloading
}

for(i=0;i<4;i++){
    task()
}

这两种都是串行的代码模式。画图描述:

理解并发和并行的区别

并行模式

并行意味着可以同时取得多个任务,并同时去执行所取得的这些任务。并行模式相当于将长长的一条队列,划分成了多条短队列,所以并行缩短了任务队列的长度

并行的效率从代码层次上强依赖于多进程/多线程代码,从硬件角度上则依赖于多核cpu。

对于单进程/单线程,由于只有一个进程/线程在执行,所以尽管同时执行所取得的多个任务,但实际上这个进程/线程是不断的在多任务之间切换,一会执行一下这个,一会执行一下那个,就像是一个人在不同地方之间来回奔波。所以,单进程/线程的并行,效率比串行更低。

对于多进程/多线程,各进程/线程都可以执行各自所取得的任务,这是真正的并行。

但是,还需要考虑硬件层次上cpu核心数,如果只有单核cpu,那么在硬件角度上这单核cpu一次也只能执行一个任务,上面多进程/多线程的并行也并非真正意义上的并行。只有多核cpu,并且多进程/多线程并行,才是真正意义上的并行。

如下图,是多进程/多线程(2个工作者)的并行:

理解并发和并行的区别

并发

理解并发和并行的区别

并发是一种现象,表示多个任务同时涌入的情况。

比如同时500个http请求涌向了web服务器。实际上对于cpu来说,操作系统上要执行的那些进程也是一种并发现象:这些等待执行的进程全部都需要cpu。

区分并发和并行是很简单的,并发是一种现象,并行是一种执行模式,是处理并发现象的一种方案

有时候也将并发当成任务,比如500并发数意味着500个任务,这500个任务可以是单进程/单线程方式处理的,这时表示的是并发不并行的模式(coroutine就是典型的并发不并行),也可以是多进程/多线程方式处理的,这时表示的是并发且并行模式。

要解决大并发问题,通常是将大任务分解成多个小任务。由于可能会从任一小任务处执行:

  • 可能出现一个小任务执行了多次,还没开始下个任务的情况。这时一般会采用队列或类似的数据结构来存放各个小任务的成果
  • 可能出现还没准备好第一步就执行第二步的可能。这时,一般采用多路复用或异步的方式,比如只有准备好产生了事件通知才执行某个任务
  • 可以多进程/多线程的方式并行执行这些小任务,也可以单进程/单线程执行这些小任务,这时很可能要配合多路复用才能达到较高的效率

看图非常容易理解:

理解并发和并行的区别

上图中将一个任务中的三个步骤取柴、运柴、卸柴划分成了独立的小任务,有取柴的老鼠,有运柴的老鼠,有卸柴烧火的老鼠。

如果上图中所有的老鼠都是同一只,那么是串行并发的,如果是不同的多只老鼠,那么是并行并发的

总结

并行和串行:

  • 串行:一次只能取得一个任务并执行这一个任务
  • 并行:可以同时通过多进程/多线程的方式取得多个任务,并以多进程或多线程的方式同时执行这些任务
  • 注意点:
    • 如果是单进程/单线程的并行,那么效率比串行更差
    • 如果只有单核cpu,多进程并行并没有提高效率
    • 从任务队列上看,由于同时从队列中取得多个任务并执行,相当于将一个长任务队列变成了短队列

并发:

  • 并发是一种现象:一次性涌入多个需要被处理的任务
  • 这些任务可能是并行执行的,也可能是串行执行的
  • 解决大并发的一个思路是将大任务分解成多个小任务:
    • 以多进程/多线程并行的方式去执行这些小任务
    • 以单进程/单线程配合多路复用执行这些小任务