Golang – 并发 vs 并行 vs 顺序执行

huangapple go评论66阅读模式
英文:

Golang - Concurrency vs Parallelism vs Sequential

问题

我目前正在学习Go语言,对于并发、并行和顺序之间的区别感到相当困惑。

假设我们有一个进程,它会爬取一个包含5个URL的切片,并将内容粘贴到一个文本文件中。这个进程每个URL需要2秒钟。

  • 顺序执行 -> 需要10秒钟,因为它一个接一个地执行。
  • 并行执行 -> 需要少于10秒钟,因为它同时执行它们,但使用了多个线程或处理器。
  • 并发执行 -> 需要少于10秒钟,但它不需要多个线程或处理器。

我不确定我理解得是否正确。我的问题是:

我读到并行性是同时进行多个任务(例如同时听音乐和运行),而并发性是同时处理多个任务(例如在熨烫衬衫的同时准备早餐)。

但是如果是这样的话,为什么并发性不需要10秒钟才能完成呢?因为归根结底,你并不是同时做所有的事情,而只是一点一点地完成所有的事情,直到全部完成。

英文:

I am learning Go at the moment and got quite frustrated understanding the different between Concurrency vs Parallelism vs Sequential.

Let's say we have a process that scraps a slice of 5 URLs and paste the content in a text file. The process takes 2 seconds per URL.

  • Sequentially -> it takes 10 seconds since it does one after the other
  • Parallel -> takes less than 10 seconds since it does them simultaneously but using multiple threads or processors.
  • Concurrently -> takes less than 10 seconds but it does not require multiple threads or processors.

Not sure if I am right until here. My questions are:

I read that parallelism does things simultaneously (running and listening to music for example) and concurrency handles things at the same time (getting breakfast done while ironing shirts for example).

But if that's the case, why is concurrency not taking 10 seconds to complete since at the end of the day you are not doing everything at the same time but just doing bits of everything until you complete it all?

答案1

得分: 4

这里有一个类比来解释。

你需要煎5个荷包蛋。煮鸡蛋的方法是将鸡蛋打在煎锅上,等待几分钟,然后取出。

  • 顺序方法是先完全煎熟第一个鸡蛋,然后完全煎熟第二个鸡蛋,以此类推,直到你有5个煎蛋。

  • 并行方法是雇佣5个厨师,告诉他们每个人煎一个鸡蛋,然后等待他们全部完成。

  • 并发方法是你自己煮5个鸡蛋,就像你实际做的那样。也就是说,你迅速地将每个鸡蛋打在锅里,然后在它们准备好时取出。

你能够节省时间而不必雇佣5个厨师的原因是,限制你速度的不是厨师的数量。煮鸡蛋需要几分钟,但只需要你的注意力和双手在开始和结束时的几秒钟。

Go运行时和现代操作系统运行时也是类似聪明的。它们知道当你的线程在等待接收网络响应时,处理器可以寻找其他事情来占用它的注意力。

并发的更大图景主要关注的不是处理器的数量,而是资源争用。任务的执行需要资源,我们不能使用超过可用资源的数量。处理器是一种资源,但还有内存存储、内存带宽、网络带宽、文件句柄等等。

英文:

Here's an analogy to explain.

You need to fry 5 eggs, sunny side up. To cook an egg you crack it onto the griddle, wait for a few minutes, then take it off.

  • The sequential approach is to fry the first egg to completion, then fry the second egg to completion, and so on, until you have 5 fried eggs.

  • The parallel approach is to hire 5 cooks, tell each of them to fry an egg, and wait until they are all finished.

  • The concurrent approach is that you cook all 5 eggs yourself the way you would actually do it. That is, you quickly crack each egg onto the pan, then take each one off when it's ready.

The reason you're able to save time without having to hire 5 cooks is because the number of cooks wasn't what was limiting you from going faster. It takes a couple minutes to cook an egg, but it only occupies your attention and your hands for a few seconds at the beginning and end.

The Go runtime and modern OS runtimes are similarly smart. They know that while your thread is waiting to receive a network response, the processor can look for other things to occupy it's attention.

The larger picture of concurrency is concerned not primarily with the number of processors, but with resource contention in general. The execution of tasks demands resources, and we cannot use more resources than are available. Processors are one resource, but there is also memory storage, memory bandwidth, network bandwidth, file handles, and the list goes on.

huangapple
  • 本文由 发表于 2022年11月23日 18:33:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/74545387.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定