From 3af81d821dbdf7cd5f472b9cf27a5459d45c2d96 Mon Sep 17 00:00:00 2001 From: lijinpeng Date: Sun, 23 Jan 2022 13:48:34 +0800 Subject: [PATCH] Minor update in concurrency-parallelism.md --- .../concurrency-parallelism.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md b/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md index 5f314a2e..bc5a4d5d 100644 --- a/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md +++ b/book/contents/advance/concurrency-with-threads/concurrency-parallelism.md @@ -1,6 +1,6 @@ # 并发和并行 -> 并发是同一时间应对多件事情的能力 - [Rob Pike](https://baike.baidu.com/item/罗布·派克/10983505) +> 并发是同一时间应对多件事情的能力 - [Rob Pike](https://en.wikipedia.org/wiki/Rob_Pike) 并行和并发其实并不难,但是也给一些用户造成了困扰,因此我们专门开辟一个章节,用于讲清楚这两者的区别。 @@ -11,15 +11,15 @@ 上图很直观的体现了: -- 并发是多个队列使用同一个咖啡机,然后两个队列轮换着使用(未必是1:1轮换,也可能是其它轮换规则),最终每个人都能接到咖啡 -- 并行是每个队列都拥有一个咖啡机,最终也是每个人都能接到咖啡,但是效率更高,因为同时可以有两个人在接咖啡 +- **并发(Concurrent)** 是多个队列使用同一个咖啡机,然后两个队列轮换着使用(未必是1:1轮换,也可能是其它轮换规则),最终每个人都能接到咖啡 +- **并行(Parallel)** 是每个队列都拥有一个咖啡机,最终也是每个人都能接到咖啡,但是效率更高,因为同时可以有两个人在接咖啡 当然,我们还可以对比下串行:只有一个队列且仅使用一台咖啡机,哪怕前面那个人接咖啡时突然发呆了几分钟,后面的人也只能等他结束才能继续接。可能有读者有疑问了,从图片来看,并发也存在这个问题啊,前面的人抽了几分钟不接怎么办?很简单,另外一个队列的人把他推开就行了,自己队友不能在背后开枪,但是其它队的可以:) 在正式开始之前,先给出一个结论:**并发和并行都是对"多任务"处理的描述,其中并发是轮流处理,而并行是同时处理**。 ## CPU多核 -现在的个人计算机动辄拥有十来个核心(M1 Max/Itel 12代),如果使用串行的方式那真是太低调了,因此我们把各种任务简单分成多个队列,每个队列都交给一个cpu核心去执行,当某个cpu核心没有任务时,它还能去其它核心的队列中偷任务(真·老黄牛),这样就实现了并行化处理。 +现在的个人计算机动辄拥有十来个核心(M1 Max/Intel 12代),如果使用串行的方式那真是太低调了,因此我们把各种任务简单分成多个队列,每个队列都交给一个cpu核心去执行,当某个cpu核心没有任务时,它还能去其它核心的队列中偷任务(真·老黄牛),这样就实现了并行化处理。 #### 单核心并发 那问题来了,在早期只有一个CPU核心时,我们的任务是怎么处理的呢?其实聪明的读者应该已经想到,是的,并发解君愁。当然,这里还得提到操作系统的多线程,正是操作系统多线程 + CPU核心,才实现了现代化的多任务操作系统。 @@ -29,7 +29,7 @@ 相信大家都看出来了:**CPU核心**对应的是上图的咖啡机,而**多个线程的任务队列**就对应的多个排队的队列,最终受限于CPU核心数, 每次只会有一个任务被处理。 -和排队一样,假如某个任务执行时间过长,就会导致用户界面的假死(相信使用windows的同学或多或少都碰到或者假死的问题), 那么就需要CPU的任务调度了(真实CPU和调度很复杂,我们这里做了简化),有一个调度器会按照某些条件从队列中选择任务进行执行,并且当一个任务执行时间过长时,会强行切换该任务到后台中(或者放入任务队列,真实情况很复杂!),去执行新的任务。 +和排队一样,假如某个任务执行时间过长,就会导致用户界面的假死(相信使用Windows的同学或多或少都碰到过假死的问题), 那么就需要CPU的任务调度了(真实CPU的调度很复杂,我们这里做了简化),有一个调度器会按照某些条件从队列中选择任务进行执行,并且当一个任务执行时间过长时,会强行切换该任务到后台中(或者放入任务队列,真实情况很复杂!),去执行新的任务。 不断这样的快速任务切换,对用户而言就实现了表面上的多任务同时处理,但是实际上最终也只有一个CPU核心在不停的工作。 @@ -46,9 +46,9 @@ ## 正式的定义 -如果某个系统支持两个或者多个动作的同时存在,那么这个系统就是一个并发系统。如果某个系统支持两个或者多个动作同时执行,那么这个系统就是一个并行系统。并发系统与并行系统这两个定义之间的关键差异在于**“存在”**这个词。 +如果某个系统支持两个或者多个动作的**同时存在**,那么这个系统就是一个并发系统。如果某个系统支持两个或者多个动作**同时执行**,那么这个系统就是一个并行系统。并发系统与并行系统这两个定义之间的关键差异在于 **“存在”** 这个词。 -在并发程序中可以同时拥有两个或者多个线程。这意味着,如果程序在单核处理器上运行,那么这两个线程将交替地换入或者换出内存。这些线程是**同时“存在”**的——每个线程都处于执行过程中的某个状态。如果程序能够并行执行,那么就一定是运行在多核处理器上。此时,程序中的每个线程都将分配到一个独立的处理器核上,因此可以同时运行。 +在并发程序中可以同时拥有两个或者多个线程。这意味着,如果程序在单核处理器上运行,那么这两个线程将交替地换入或者换出内存。这些线程是 **同时“存在”** 的——每个线程都处于执行过程中的某个状态。如果程序能够并行执行,那么就一定是运行在多核处理器上。此时,程序中的每个线程都将分配到一个独立的处理器核上,因此可以同时运行。 相信你已经能够得出结论——**“并行”概念是“并发”概念的一个子集**。也就是说,你可以编写一个拥有多个线程或者进程的并发程序,但如果没有多核处理器来执行这个程序,那么就不能以并行方式来运行代码。因此,凡是在求解单个问题时涉及多个执行流程的编程模式或者执行行为,都属于并发编程的范畴。