【不懂并行和并发?一文彻底搞懂并行和并发的区别】假设这堆柴需要运送4次才能运完 , 那么当写下的代码类似于下面这种时 , 那么就是串行非并发的模式:
for(i=0;i<4;i++){get()carry()unload()}
或者 , 将三个过程的代码全部集中到一个函数中也是如此:
func task {getingcarryingunloading}for(i=0;i<4;i++){task()}
这两种都是串行的代码模式 。画图描述:
文章插图
并行模式
并行意味着可以同时取得多个任务 , 并同时去执行所取得的这些任务 。并行模式相当于将长长的一条队列 , 划分成了多条短队列 , 所以并行缩短了任务队列的长度 。
正如前面所举的两同学进办公室的例子 , 串行的方式下 , 必须1个同学进入后第二个同学才进入 , 队列长度为2 , 而并行方式下可以同时进入 , 队列长度减半了 。
并行的效率从代码层次上强依赖于多进程/多线程代码 , 从硬件角度上则依赖于多核CPU 。
对于单进程/单线程 , 由于只有一个进程/线程在执行 , 所以尽管同时执行所取得的多个任务 , 但实际上这个进程/线程是不断的在多任务之间切换 , 一会执行一下这个 , 一会执行一下那个 , 就像是一个人在不同地方之间来回奔波 。所以 , 单进程/线程的并行 , 效率比串行更低 。
对于多进程/多线程 , 各进程/线程都可以执行各自所取得的任务 , 这是真正的并行 。
但是 , 还需要考虑硬件层次上CPU核心数 , 如果只有单核CPU , 那么在硬件角度上这单核CPU一次也只能执行一个任务 , 上面多进程/多线程的并行也并非真正意义上的并行 。只有多核CPU , 并且多进程/多线程并行 , 才是真正意义上的并行 。
如下图 , 是多进程/多线程(2个工作者)的并行:
文章插图
并发
并发表示多个任务同时都要执行的现象 , 更详细的概念前面已经说面的够具体了 。
其实 , 很多场景下都会使用并发的概念 。比如同时500个http请求涌向了web服务器 , 比如有时候说并发数是1000等 。
有时候也将并发当成任务 , 比如500并发数意味着500个任务 , 表示的是在一个特定的时间段内(约定俗成的大家认为是1秒)可以完成500个任务 。这500个任务可以是单进程/单线程方式处理的 , 这时表示的是并发不并行的模式(coroutine就是典型的并发不并行) , 即先执行完一个任务后才执行另一个任务 , 也可以是多进程/多线程方式处理的 , 这时表示的是并发且并行模式 。
要解决大并发问题 , 通常是将大任务分解成多个小任务 。很典型的一个例子是处理客户端的请求任务 , 这个大任务里面包含了监听并建立客户端的连接、处理客户端的请求、响应客户端 。但基本上所有这类程序 , 都将这3部分任务分开了:在执行任何一个小任务的时候 , 都可以通过一些手段使得可以执行其它小任务 , 比如在处理请求的时候 , 可以继续保持监听状态 。
由于操作系统对进程的调度是随机的 , 所以切分成多个小任务后 , 可能会从任一小任务处执行 。这可能会出现一些现象:
- 可能出现一个小任务执行了多次 , 还没开始下个任务的情况 。这时一般会采用队列或类似的数据结构来存放各个小任务的成果 。比如负责监听的进程已经执行了多次 , 建立了多个连接 , 但是还没有调度到处理请求的进程去处理任何一个请求 。
- 可能出现还没准备好第一步就执行第二步的可能 。这时 , 一般采用多路复用或异步的方式 , 比如只有准备好产生了事件通知才执行某个任务 。比如还没有和任何一个客户端建立连接时 , 就去执行了处理请求的进程 。
- 可以多进程/多线程的方式并行执行这些小任务 。也可以单进程/单线程执行这些小任务 , 这时很可能要配合多路复用才能达到较高的效率
推荐阅读
- 马鞭草和马鞍草,马鞭草和鼠尾草怎么区别
- 槐角治痔疮,治痔疮的根治办法
- 84消毒液能杀死霉菌和细菌吗 84消毒液能除霉吗
- VS Code 安装和设置Visual Studio Code的简要教程
- 陈皮和哪些茶搭配最好,陈皮与什么泡茶最好老友茶告诉你陈皮和哪些茶搭配最好
- 生啤的成分和工艺,古法生晒工艺
- 星月菩提等级价格表,千眼菩提和星月菩提的区别
- 陈皮泡水喝的功效和禁忌,陈皮泡水喝的功效
- Data Mesh的原则和逻辑架构
- API攻击原理,以及如何识别和预防