并发和并行有什么区别?
并发和并行有什么区别?
这个来源给了我很好的解释:
并发(Concurrency)是指应用程序处理多个任务的方式。应用程序可以一个接一个地处理任务(串行),也可以同时处理多个任务(并行)。
而并行(Parallelism)则是指应用程序处理每个单独任务的方式。应用程序可以从头到尾依次处理任务,也可以将任务分成子任务并并行完成。
可以看出,应用程序可以是并发但不是并行的。这意味着它可以同时处理多个任务,但不会将任务拆分为子任务。
应用程序也可以是并行但不是并发的。这意味着应用程序一次只处理一个任务,而这个任务被拆分为可并行处理的子任务。
此外,应用程序既不是并发也不是并行的情况也存在。这意味着它一次只处理一个任务,且该任务永远不会被拆分为可并行执行的子任务。
最后,应用程序也可以同时具备并发和并行的特性,即它可以同时处理多个任务,并将每个任务拆分为子任务以实现并行处理。然而,在这种情况下,与单独使用并发或并行相比,一些并发和并行的优势可能会丧失,因为计算机中的CPU已经保持了合理的繁忙状态。同时使用可能只会带来小幅度的性能提升,甚至会导致性能下降。
Pike对"并发(concurrency)"的理解是一种有意的设计和实现决策。一个具备并发能力的程序设计可能表现出行为上的"并行(parallelism)",这取决于运行环境。
你不希望一个没有为并发而设计的程序表现出并行性。:-) 但在相关因素(功耗、性能等)带来净收益的范围内,你希望采用最大并发设计,以便主机系统在可能的情况下可以并行执行。
Pike的Go编程语言极端地体现了这一点:他的函数都是可以正确并发运行的线程,即调用一个函数总是会创建一个线程,如果系统有能力,它将与调用者并行运行。在他的世界里,拥有数百甚至数千个线程的应用程序是再正常不过的事情了。(我不是 Go 专家,这只是我的看法。)
并发简单地意味着有多个任务在运行(不一定是并行的)。例如,假设我们有3个任务,则在任何时刻:可能有多个正在运行,或者全部同时运行。
并行意味着它们实际上是并行运行的。因此,在这种情况下,所有三个任务必须同时运行。
并行编程:程序员知道程序将在拥有多个处理器/核心的计算机上运行,并希望利用多个核心。程序员将一个 CPU 密集型的计算任务分成多个子任务,每个子任务在一个线程中运行,一旦线程完成,它们的结果就会被合并到总结果中(分而治之)。例如,将某些矩阵处理代码分解为并行处理矩阵部分的子任务。每个核心将执行一个线程来处理子任务(或者如果线程数大于核心数,则同时执行多个线程)。程序员必须在这里应用并发编程技术,但她也关注将任务分解为子任务并组合结果。例如,在 Java 中,程序员可以使用 ParallelStreams 自动拆分数据并组合结果。如果程序员知道程序将在单核处理器上执行,则将 CPU 密集型任务分解为多个线程是没有收益的。(摘自 Doug Leah 的《Java 并发编程:设计原则和模式,第二版,1999年,第343页)
并行程序专门设计用于利用多个 CPU 解决计算密集型问题。
选自这篇博客的摘录:
并发和并行的区别:并发是编程术语。它涉及多个任务在没有特定顺序的重叠时间段内开始运行和完成。并发由操作系统管理。当多个线程想要访问同一资源时,线程会出现竞争条件问题。此外,它们还会出现死锁,其中它们互相等待,防止自己运行。例如,您想在吃东西时说话。首先,您需要吞下嘴里的食物或停止咀嚼,然后才能说话(您正在切换线程),说完话后您可以再咬一口。
并行是硬件术语。它涉及多个任务在具有多个计算资源的硬件上实际同时运行,例如多核处理器。如果您能够在咀嚼食物时说话,这就是并行性。并行的一个例子是,一个人可以同时唱歌和跳舞。