并发使两个任务在单独的线程上并行运行。但是,异步方法并行运行,但在同一1个线程上。如何实现的?另外,并行性如何?
这三个概念之间有什么区别?
Answers:
并发和并行实际上与您正确推测的原理相同,两者都与同时执行的任务有关,尽管我会说并行任务应该是真正的多任务处理,“同时”执行,而并发可能意味着任务正在共享执行线程,而看上去仍在并行执行。
异步方法与前两个概念没有直接关系,异步用于表示并发或并行任务的印象,但实际上,异步方法调用通常用于需要完成当前应用程序工作的过程,而我们不这样做不想等待并阻止我们的应用程序等待响应。
例如,从数据库获取数据可能会花费一些时间,但是我们不想阻塞UI来等待数据。异步调用获取一个回调引用,并在远程系统发出请求后立即将执行返回给您的代码。当远程系统执行所需的任何处理时,您的UI可以继续对用户作出响应,一旦将数据返回给回调方法,该方法就可以适当地更新UI(或移交该更新)。
从用户角度来看,它看起来像多任务处理,但可能并非如此。
编辑
可能值得补充的是,在许多实现中,异步方法调用将导致线程被启动,但这不是必需的,它实际上取决于正在执行的操作以及如何将响应通知给系统。
简而言之,
并发是指多个任务,它们以重叠的时间段(没有特定的顺序)开始,运行和完成。并行是指多个任务或唯一任务的多个部分实际上在同一时间(例如在多核处理器上)运行。
请记住,并发和并行性不是一回事。
并发与并行之间的差异
现在让我们列出并发和并行之间的显着差异。
并发是指两个任务可以在重叠的时间段内启动,运行和完成。并行是指任务实际上在同一时间运行,例如。在多核处理器上。
并发是独立执行进程的组成,而并行是同时执行(可能相关)计算。
并发就是一次处理很多事情。并行是关于一次做很多事情。
一个应用程序可以是并发的,但不能是并行的,这意味着它可以同时处理多个任务,但不会同时执行两个任务。
一个应用程序可以是并行的,但不能是并发的,这意味着它可以同时处理多核CPU中一个任务的多个子任务。
一个应用程序既不能是并行的,也不能是并发的,这意味着它一次顺序地处理所有任务。
一个应用程序可以是并行的,也可以是并发的,这意味着它可以同时在多核CPU中同时处理多个任务。
并发
当我们谈论至少两个或更多任务时,并发本质上是适用的。当一个应用程序实际上能够同时执行两个任务时,我们将其称为并发应用程序。尽管这里的任务看起来像同时运行,但是从本质上讲它们可能不一样。它们利用操作系统的CPU时间分片功能,其中每个任务运行其任务的一部分,然后进入等待状态。当第一个任务处于等待状态时,CPU被分配给第二个任务以完成它的一部分任务。
因此,操作系统根据任务的优先级分配CPU和其他计算资源,例如内存;依次处理所有任务,并给他们完成任务的机会。对于最终用户,似乎所有任务都是并行运行的。这称为并发。
平行性
并行不需要两个任务存在。通过使用CPU的多核基础结构,通过为每个任务或子任务分配一个内核,它实际上可以同时运行部分任务或多个任务。
并行性本质上要求具有多个处理单元的硬件。在单核CPU中,您可能会获得并发性,但不能获得并行性。
异步方法
这与并发性和并行性无关,异步用于表示并发或并行任务的印象,但是有效地通常将异步方法调用用于需要在当前应用程序之外工作的进程,而我们不想等待并阻止我们的应用程序等待响应。
在几种情况下可能发生并发:
异步—这意味着您的程序执行非阻塞操作。例如,它可以通过HTTP发起对远程资源的请求,然后在等待接收响应的同时继续执行其他任务。这有点像您发送电子邮件,然后继续生活而无需等待响应。
并行性-这意味着您的程序通过将工作分解为任务来利用多核计算机的硬件来同时执行任务,每个任务都在单独的内核上执行。有点像在洗澡时唱歌:实际上,您实际上在同时做两件事。
多线程—这是一种软件实现,允许同时执行不同的线程。即使多线程程序在单核计算机上运行,它似乎也同时在执行多项操作。这有点像通过各种IM窗口与不同的人聊天;尽管实际上是来回切换,但最终结果是您同时进行多个对话。
每个人都在将异步与并行性或并发性相关联方面遇到麻烦,因为异步不是并行或并发的反义词。它是“同步”的反义词。这只是表明某个东西(在这种情况下为线程)是否将与其他东西(在这种情况下为另一个线程)同步。
并发意味着可以同时但不必同时执行多个任务。当您必须执行多个任务但又只有一个资源时,我们便开始并发。在单核环境中,并发是通过上下文切换来实现的。
并行性就像同时执行多个任务一样,就像您可以一起唱歌和洗澡一样。现在,您正在并行执行任务。
术语异步与线程执行有关。在异步模型中,执行一个任务时,您可以切换到其他任务,而无需等待上一个任务完成。
异步编程可以帮助我们实现并发。在多线程环境中进行异步编程是一种实现并行性的方法。
“同步和异步是编程模型。并发和并行是执行任务的方式...”。来源:https://medium.com/better-programming/sync-vs-async-vs-concurrent-vs-parallel-5754cdb60f66
换句话说,sync和async描述了程序在执行函数调用时的执行方式(它将等待还是继续执行?),而并发和并行描述了函数(任务)的执行方式(并发=可能在以下位置执行)同一时间,并行=有效地同时执行)。
并发
并发意味着应用程序同时(同时)在一项以上的任务上取得进展。好吧,如果计算机只有一个CPU,则应用程序可能无法在同一时间同时完成一项以上的任务,而是在应用程序中一次要处理多个任务。在开始下一项任务之前,它并没有完全完成一项任务。
平行性
并行是指应用程序将其任务分解为较小的子任务,这些子任务可以并行处理,例如在多个CPU上同时进行。
并发与并行的细节
如您所见,并发与应用程序如何处理其执行的多个任务有关。应用程序可以一次(顺序)处理一个任务,也可以同时(并行)处理多个任务。
另一方面,并行性与应用程序如何处理每个单独的任务有关。应用程序可以从头到尾顺序处理任务,或者将任务拆分为可以并行完成的子任务。
如您所见,应用程序可以是并发的,但不能并行。这意味着它可以同时处理多个任务,但是这些任务不会分解为子任务。
应用程序也可以是并行的,但不能是并行的。这意味着该应用程序一次只能处理一个任务,并且该任务被分解为可以并行处理的子任务。
另外,一个应用程序既不能是并发的也不可以是并行的。这意味着它一次只能处理一个任务,并且该任务永远不会分解为子任务以并行执行。
最后,应用程序也可以是并发和并行的,因为它既可以同时处理多个任务,又可以将每个任务分解为多个子任务以并行执行。但是,在这种情况下,并发性和并行性的某些好处可能会丢失,因为计算机中的CPU已经足够合理地仅使用并发性或并行性。结合使用它可能只会导致很小的性能提升甚至性能下降。在盲目采用并发并行模型之前,请确保进行分析和衡量。
来自http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html
平行 :这是一个广义术语,表示两段代码“同时”执行该代码。它是“真正的”并行性还是通过某种巧妙的设计模式伪造都没有关系。关键是您可以同时启动“任务”,然后分别控制它们(使用互斥锁和所有适当的技巧)。但是通常您更喜欢仅将“并行”一词用于“真正的”并行性,例如:通过非合作多任务(无论是CPU / GPU内核)还是仅在软件级别通过让OS管理它来实现在非常低的水平)。人们不愿意为伪造并行性的复杂顺序代码说“并行”,例如在浏览器窗口的javascript中会发现这种情况。因此,人们在这个线程中说“异步与并行性无关”的原因。可以,但是不要混淆它们。
并发:没有并行性就不可能有并发性(无论是模拟的还是真实的,如上所述),但是该术语专门针对以下事实:两个系统将在某个时间点尝试同时访问同一资源。它着重强调了您将不得不处理的事实。
异步:每个人都是对的,说异步与并行无关,但是它为它铺平了道路(使事情变得平行或不平行的负担在您身上-请继续阅读)。
“异步”指的是并行化的表示形式,它使并行化中通常涉及的三个基本方面形式化:1)定义任务的初始化(例如,启动时间以及获得的参数),2)完成后必须执行的操作,以及3)代码之间应该继续做什么。
但是它仍然只是语法(通常以回调方法表示)。在后台,底层系统可能会简单地决定这些所谓的“任务”只是要堆积的代码片段,直到完成当前正在执行的代码为止。然后,它们一个接一个地解堆并顺序执行它们。或不。它还可能为每个任务创建一个线程并并行运行它们。谁在乎?该部分不包含在概念中;)
我将简短扼要地介绍这些概念。
并发与并行-任务执行方式。
以现实生活中的例子为例:这是一个挑战,要求您既要吃整个大蛋糕,又要唱整首歌。如果您是唱整首歌并完成蛋糕的最快人,那么您将获胜。因此,规则是您同时唱歌和吃饭。您如何做不属于规则。您可以吃整个蛋糕,然后唱整首歌,也可以吃半个蛋糕,然后唱半首歌,然后再做一次,等等。
并行是一种特定的并发类型,其中任务实际上是同时执行的。在计算机科学中,并行性只能在多核环境中实现。
同步与异步-编程模型。
同步时,您将代码编写为从上到下依次执行的步骤。在异步编程模型中,您将代码编写为任务,然后并行执行。同时执行意味着所有任务都可能同时执行。
在这里我用一些例子解释
甲GPU使用并行处理来处理相同的代码块(AKA内核上千种物理和逻辑线程)。理想情况下,该过程同时开始和结束所有线程。没有超线程的单个CPU内核无法执行并行处理。
注意:我之所以说是理想的,是因为当您在具有6M线程的硬件上运行大小为7M的内核时,它必须在所有6M线程上并行运行两次相同的代码,同时每次消耗6M线程。
注意:并行性不仅限于GPU。
一个Web服务收到许多小请求,在实时性和需要处理这些请求的不同,在任何时间,并独立于其他请求或任何内部工作。但是,您希望Web服务始终启动并运行,而不破坏数据状态或系统运行状况。
想象一个用户更新一条记录,而另一个用户同时删除同一条记录。
注意:这些请求通常消耗一些必不可少的资源,例如内存,数据库连接或带宽。但是,您希望Web服务始终保持响应状态。异步是使其响应而不是并发的关键
如果一个繁重的进程(例如I / O操作)在GUI线程上运行,则很容易阻塞GUI(或其他基本线程)。为了保证UI响应能力,可以异步执行繁重的过程。这是更好地运行类似的异步操作一次一个。例如,如果同时运行多个IO绑定操作,可能会明显减慢速度,因此最好将它们完成排队以启动
注意:并发执行的异步操作(即一次执行一次以上)是并发操作。
注意:并发性和异步性常常相互混淆。并发是指系统的不同部分协同工作而不会互相干扰(这些问题通常通过锁,信号灯或互斥锁解决)。异步是您实现响应能力(例如线程)的方式。
*注意:异步和多线程经常相互混淆。异步代码不一定涉及新线程。它可以是硬件操作,也可以是Stephan所说的纯操作,请阅读此内容
例如,在下面的WPF + C#代码中,await Task.Run(()=> HeavyMethod(txt))
正在解决异步问题,同时 textBox.Dispatcher.Invoke
正在解决并发问题:
private async void ButtonClick(object sender, RoutedEventArgs e)
{
// run a method in another thread
await Task.Run(()=> HeavyMethod(txt));
// modify UI object in UI thread
txt.Text = "done";
}
// This is a thread-safe method. You can run it in any thread
internal void HeavyMethod(TextBox textBox)
{
while (stillWorking)
{
// use Dispatcher to safely invoke UI operations
textBox.Dispatcher.Invoke(() =>
{
// UI operations outside of invoke will cause ThreadException
textBox.Text += ".";
});
}
}