提问人:tush1r 提问时间:4/14/2009 最后编辑:Mateen Ulhaqtush1r 更新时间:9/25/2022 访问量:1098289
异步执行与同步执行。有什么区别?[关闭]
Asynchronous vs synchronous execution. What is the difference? [closed]
问:
异步执行和同步执行有什么区别?
答:
简单地说,异步执行就是在后台做一些事情。
例如,如果要从 Internet 下载文件,可以使用同步函数来执行此操作,但它会阻止线程,直到文件完成下载。这可能会使应用程序对任何用户输入无响应。
相反,您可以使用异步方法在后台下载文件。在这种情况下,下载函数会立即返回,程序会继续正常执行。所有下载操作都在后台完成,完成后您的程序将收到通知。
评论
当您同步执行某些操作时,请等待它完成,然后再继续执行另一个任务。当您异步执行某些任务时,您可以在另一个任务完成之前继续执行该任务。
在操作系统的上下文中,这对应于在“线程”上执行进程或任务。线程是作为工作单元存在的一系列命令(代码块)。操作系统在处理器内核上运行给定的线程。但是,处理器内核一次只能执行单个线程。它没有同时运行多个线程的概念。操作系统可以通过运行每个线程一小段时间(例如 1 毫秒)并在线程之间连续切换来提供一次运行多个线程的错觉。
现在,如果将多个处理器内核引入组合中,则线程可以同时执行。操作系统可以将时间分配给第一个处理器内核上的一个线程,然后将相同的时间块分配给另一个处理器内核上的另一个线程。所有这些都是关于允许操作系统管理任务的完成,同时您可以继续编写代码并执行其他操作。
异步编程是一个复杂的话题,因为当您可以同时进行异步编程时,它们是如何联系在一起的语义。有许多关于该主题的文章和书籍;看一看!
评论
同步执行意味着执行发生在单个系列中。.如果要调用这些例程,将运行,然后完成,然后将开始,然后完成,然后将开始,依此类推。A->B->C->D
A
B
C
使用异步执行,您可以开始一个例程,并在开始下一个例程时让它在后台运行,然后在某个时候说“等待此完成”。它更像是:
开始 等待完成A->B->C->D->
A
优点是您可以在仍在运行时执行 、 和/或 (在后台,在单独的线程上),因此您可以更好地利用您的资源并减少“挂起”或“等待”。B
C
D
A
评论
同步意味着调用方等待响应或完成,异步表示调用方继续,稍后响应(如果适用)。
举个例子:
static void Main(string[] args)
{
Console.WriteLine("Before call");
doSomething();
Console.WriteLine("After call");
}
private static void doSomething()
{
Console.WriteLine("In call");
}
这将始终输出:
Before call
In call
After call
但是,如果我们要进行异步(多种方式),那么输出可能会变成:doSomething()
Before call
After call
In call
因为进行异步调用的方法将立即继续下一行代码。我说“可能”,因为异步操作无法保证执行顺序。它也可以像原始一样执行,具体取决于线程时序等。
同步/异步与多线程无关。
“同步”或“同步”的意思是“连接”,或以某种方式“依赖”。换句话说,两个同步任务必须相互感知,并且一个任务必须以某种依赖于另一个任务的方式执行,例如等待启动,直到另一个任务完成。
异步意味着它们是完全独立的,无论是在启动还是在执行中,任何一方都不得以任何方式考虑另一方。
同步(一个线程):
1 thread -> |<---A---->||<----B---------->||<------C----->|
同步(多线程):
thread A -> |<---A---->|
\
thread B ------------> ->|<----B---------->|
\
thread C ----------------------------------> ->|<------C----->|
异步(一个线程):
A-Start ------------------------------------------ A-End
| B-Start -----------------------------------------|--- B-End
| | C-Start ------------------- C-End | |
| | | | | |
V V V V V V
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->|
异步(多线程):
thread A -> |<---A---->|
thread B -----> |<----B---------->|
thread C ---------> |<------C--------->|
- 任务 A、B、C 的起点和终点用 、 字符表示。
<
>
- 由竖条表示的 CPU 时间片
|
从技术上讲,同步/异步的概念实际上与线程没有任何关系。虽然,一般来说,发现在同一线程上运行的异步任务是不寻常的,但有可能(参见下面的示例),并且发现两个或多个任务在单独的线程上同步执行是很常见的......不,同步/异步的概念仅与是否可以在另一个(第一个)任务完成之前启动第二个或后续任务有关,或者它是否必须等待。仅此而已。在什么线程(或线程)、进程、CPU 或什么硬件上执行任务并不重要。事实上,为了说明这一点,我编辑了图形来显示这一点。
异步示例:
在解决许多工程问题时,该软件旨在将整个问题分解为多个单独的任务,然后异步执行它们。反转矩阵或有限元分析问题就是很好的例子。在计算中,对列表进行排序就是一个例子。例如,快速排序例程将列表拆分为两个列表,并对每个列表执行快速排序,递归调用自身 (quicksort)。在上面的两个示例中,这两个任务可以(并且经常)异步执行。它们不需要位于单独的线程上。即使是具有一个 CPU 且只有一个执行线程的机器,也可以进行编码,以便在第一个任务完成之前启动第二个任务的处理。唯一的标准是,一个任务的结果不需要作为另一个任务的输入。只要任务的开始和结束时间重叠(仅当不需要任何一个任务的输出作为另一个任务的输入时才有可能),无论使用多少个线程,它们都是异步执行的。
同步示例:
由多个任务组成的任何流程,其中任务必须按顺序执行,但其中一个必须在另一台机器上执行(获取和/或更新数据、从金融服务获取股票报价等)。如果它位于单独的计算机上,则它位于单独的线程上,无论是同步线程还是异步线程。
评论
我认为这有点迂回的解释,但它仍然使用现实生活中的例子进行了澄清。
小例子:
假设播放音频涉及三个步骤:
- 从硬盘获取压缩的歌曲
- 解压缩音频。
- 播放未压缩的音频。
如果您的音频播放器按顺序对每首歌曲执行第 1、2、3 步,则它是同步的。您必须等待一段时间才能听到这首歌,直到歌曲真正被提取和解压缩。
如果您的音频播放器执行步骤 1、2、3 彼此独立,则它是异步的。即。 播放音频 1(步骤 3)时,如果它并行从硬盘获取音频 3(步骤 1)并行解压缩音频 2。(步骤2) 您最终会听到这首歌,而无需等待太多时间进行取物和解压。
当执行如下序列时:a>b>c>d>,如果我们在执行过程中出现以下故障:
a
b
c
fail
然后我们从头开始:
a
b
c
d
这是同步的
但是,如果我们有相同的顺序要执行:a>b>c>d>,并且中间有一个失败:
a
b
c
fail
...但是,我们不是从头开始,而是从故障点重新开始:
c
d
...这称为异步。
评论
您将同步与并行与系列混淆了。同步均值同时进行。同步意味着与每个othere相关,可以是串联的,也可以是以固定的间隔。当程序完成所有操作时,它会串联运行。获取字典...这就是为什么我们有不甜的茶。你有茶或加糖的茶。
评论
同步操作在返回给调用方之前完成其工作。
异步操作在返回给调用方后执行(大部分或全部)工作。
简单来说:
同步
您正在排队领取电影票。在你前面的每个人都得到一个之前,你无法得到一个,这同样适用于你身后排队的人。
异步
你和许多其他人一起在一家餐厅里。你点菜。其他人也可以订购他们的食物,他们不必等待您的食物煮熟并提供给您才能订购。 在厨房里,餐厅的工人不断地做饭、上菜和接单。 人们的食物一煮熟就会上桌。
评论
通过类比的简单解释
(提供故事和图片以帮助您记住)。
同步执行
我的老板是个大忙人。他让我写代码。我告诉他:好吧。我开始,他像秃鹫一样看着我,站在我身后,从我的肩膀上。我就像“伙计,WTF:你为什么不在我完成这个的时候去做点什么呢?
他说:“不,我在这里等着你,直到你完成。这是同步的。
异步执行
老板让我去做,而不是在那里等着我的工作,老板去做其他任务。当我完成我的工作时,我只是向我的老板报告并说:“我完成了!这就是异步执行。
(听我的建议:永远不要和你身后的老板一起工作。
评论
Synchronous
一次用手工作。 一次用手工作。1
Asynchronous
2
synchronous
简而言之,同步是指两个或多个进程的起点和终点,而不是它们的执行点。在此示例中,进程 A 的终结点与进程 B 的起点同步:
SYNCHRONOUS |--------A--------| |--------B--------|
另一方面,异步进程的启动和终结点不会同步:
ASYNCHRONOUS |--------A--------| |--------B--------|
如果进程 A 与进程 B 重叠,则它们同时或同步运行(字典定义),因此会造成混淆。
更新:查尔斯·布雷塔纳(Charles Bretana)改进了他的答案,所以这个答案现在只是一个简单(可能过于简化)的助记符。
评论
同步基本上意味着您一次只能执行一件事。异步意味着您可以一次执行多个事情,并且不必完成当前事情的执行才能继续下一个事情。
评论
关于同步执行的“同时”定义(有时会令人困惑),这里有一个理解它的好方法:
同步执行:代码块中的所有任务都同时执行。
异步执行:代码块中的所有任务并非同时执行。
评论
举个非常简单的例子,
同步
想象一下,3 名学生被指示在道路上进行接力赛。
第一个学生跑完她给定的距离,停下来并将接力棒传给第二个学生。没有其他人开始跑步。
1------>
2.
3.
当第二个学生取回接力棒时,她开始跑她给定的距离。
1.
2------>
3.
第二个学生解开了她的鞋带。现在她停了下来,又绑起来了。正因为如此,第二个的结束时间被延长了,第三个的开始时间被推迟了。
1.
--2.--->
3.
这种模式一直持续到第 3 名从第 2 名手中接过接力棒并完成比赛。
异步
想象一下,10个随机的人走在同一条路上。 当然,他们不是在排队,只是以不同的速度随机走在路上的不同地方。
第二个人的鞋带解开了。她停下来再次把它绑起来。
但没有人在等她把它绑起来。其他人仍然以他们以前的方式走路,以他们相同的速度。
10--> 9-->
8--> 7--> 6-->
5--> 4-->
1--> 2. 3-->
我认为一个很好的方式是经典的跑步接力赛
同步:像同一团队的成员一样,在收到接力棒(前一个进程/运行器的执行结束)之前,它们不会执行,但它们都彼此同步运行。
异步:当不同团队的成员在同一接力赛道上运行时,它们将运行和停止,彼此异步,但在同一场比赛中(整体程序执行)。
这有意义吗?
同步意味着将逐个执行队列方式执行任务。假设只有车辆需要在朋友之间共享才能到达目的地,一辆一辆的车辆将被共享。
在异步情况下,每个朋友都可以租用车辆并到达目的地。
同步与异步
同步和异步操作是关于执行顺序,与当前任务相关的下一个任务。
让我们看一下任务 2 是当前任务,任务 3 是下一个任务的示例。任务是一个原子操作 - 堆栈(方法帧)中的方法调用。
同步
表示任务将逐个执行。只有在当前任务完成后,才会启动下一个任务。在任务 2 完成之前,任务 3 不会启动。
单线程 + 同步 - 顺序
通常的执行。
伪代码:
main() {
task1()
task2()
task3()
}
多线程 + 同步 - 并行
封锁。
阻塞意味着线程只是在等待(尽管它可以做一些有用的事情,例如 Java [About] 和 [About]) 伪代码:ExecutorService
Future
main() {
task1()
Future future = ExecutorService.submit(task2())
future.get() //<- blocked operation
task3()
}
异步
意味着任务立即返回控制权,并承诺执行代码并稍后通知结果(例如回调、功能)。即使任务 2 未完成,也会执行任务 3。异步回调,完成处理程序[关于]
单线程 + 异步 - 并发
使用回调队列(Message Queue)和事件循环(Run Loop,Looper)。Event Loop 检查 Thread Stack 是否为空,如果为 true,它会将 Callback Queue 中的第一项推送到 Thread Stack 中,并再次重复这些步骤。简单的例子是按钮点击、发布事件......
伪代码:
main() {
task1()
ThreadMain.handler.post(task2());
task3()
}
多线程 + 异步 - 并发和并行
无阻塞。
例如,当您需要在不阻塞的情况下在另一个线程上进行一些计算时。伪代码:
main() {
task1()
new Thread(task2()).start();
//or
Future future = ExecutorService.submit(task2())
task3()
}
您可以使用阻塞方法或通过循环使用异步回调来使用任务 2 的结果。get()
例如,在移动世界中,我们有 UI/主线程并且我们需要下载一些东西,我们有几种选择:
sync
block - 阻止 UI 线程并等待下载完成。UI 无响应。async
callback - 使用异步回调创建一个新 tread 以更新 UI(无法从非 UI 线程访问 UI)。回调地狱。async
coroutine[About] - 具有同步语法的异步任务。它允许将下载任务(挂起功能)与UI任务混合。
[iOS同步/异步]、[Android同步/异步]
评论
Synchronize 的不同英文定义是 Here
坐标;合。
我认为这比“同时发生”更好。这也是一个定义,但我认为它不适合它在计算机科学中的使用方式。
因此,异步任务不与其他任务协同,而同步任务与其他任务协同,因此一个任务在另一个任务开始之前完成。
如何实现这一目标是另一个问题。
是的,同步意味着同时,从字面上看,它意味着一起做工作。世界上的多个人/物体可以同时做多件事,但如果我们看一下计算机,它说同步意味着过程一起工作,这意味着过程依赖于彼此的返回,这就是为什么它们以适当的顺序一个接一个地执行。而异步意味着进程不能协同工作,它们可以同时工作(如果在多线程上),但独立工作。
我创建了一个gif来解释这一点,希望对您有所帮助: 看,第 3 行是异步的,其他行是同步的。 第 3 行之前的所有行都应该等到行完成其工作之前,但由于第 3 行是异步的,下一行(第 4 行),不要等待第 3 行,但第 5 行应等待第 4 行完成其工作,第 6 行应等待第 5 行和第 7 行为 6,因为第 4、5、6、7 行不是异步的。
做早餐的说明示例:
- 倒一杯咖啡。
- 加热平底锅,然后煎两个鸡蛋。
- 煎三片培根。
- 烤两块面包。
- 在吐司中加入黄油和果酱。
- 倒入一杯橙汁。
- 如果你有烹饪经验,你可以异步执行这些指令。你会开始加热锅里的鸡蛋,然后开始培根。你把面包放在烤面包机里,然后开始鸡蛋。在流程的每一步,你都会开始一个任务,然后把注意力转向准备好让你注意的任务。
烹饪早餐是非并行异步工作的一个很好的例子。一个人(或线程)可以处理所有这些任务。继续早餐类比,一个人可以通过在第一个任务完成之前开始下一个任务来异步制作早餐。无论是否有人在看,烹饪都会进行。一旦你开始加热锅里的鸡蛋,你就可以开始煎培根了。培根开始后,您可以将面包放入烤面包机中。
对于并行算法,需要多个 cook(或线程)。一个会做鸡蛋,一个会做培根,依此类推。每个人都将专注于一项任务。每个厨师(或线程)都会被同步阻塞,等待培根准备好翻转,或者吐司爆裂。
(强调我的)
评论