Ada*_*son 1670

当您同步执行某些操作时,请等待它完成,然后再继续执行其他任务.当您异步执行某些操作时,可以在完成之前继续执行另一个任务.

话虽如此,在计算机环境中,这转化为在另一个"线程"上执行进程或任务.线程是作为工作单元存在的一系列命令(代码块).操作系统可以管理多个线程,并在切换到另一个线程之前为线程分配处理器时间的一部分("切片"),以便轮流做一些工作.在它的核心(原谅双关语),处理器可以简单地执行一个命令,它没有一次做两件事的概念.操作系统通过将时间片分配给不同的线程来模拟这一点.

现在,如果你在混合中引入多个核心/处理器,那么事情实际上可能同时发生.操作系统可以将时间分配给第一个处理器上的一个线程,然后将相同的时间块分配给另一个处理器上的另一个线程.所有这一切都是为了让操作系统能够管理您的任务完成,同时您可以继续执行代码并执行其他操作.

异步编程是一个复杂的主题,因为当你可以同时执行它们时,事物如何结合在一起的语义.有很多关于这个主题的文章和书籍; 看一看!

  • 奇怪的是,"同步"意味着"使用相同的时钟",因此当两个指令同步时,它们使用相同的时钟并且必须一个接一个地发生."异步"表示"不使用相同的时钟",因此指令不涉及彼此同步.这就是它倒退的原因,这个术语并不是指彼此之间的指示关系.它指的是每个指令与时钟的关系.希望有所帮助. (261认同)
  • 令我绝对困惑的是,同步意味着"同时",但是当在上面的意义上使用时,它意味着*顺序*,而异步意味着"不在同一时间"...... 有人可以解释这个冲突吗? (222认同)
  • @Zenph:在这种情况下,我们关注的是整个代码块.同步意味着块同时执行(但是,是的,组件是按顺序执行的).异步意味着块不是全部同时执行. (42认同)
  • 这些术语来自工程.https://en.wikipedia.org/wiki/Asynchronous_system (13认同)
  • 当程序将消息发送到队列时(如在消息传递系统中,如ActiveMQ,WebSphere MQ,HornetQ,MSMQ等),也会发生异步执行.在这种情况下,异步调用不涉及多线程编程或在OS级别处理并发. (7认同)
  • 实际上,"同步"在某种程度上意味着"连接"或"依赖".换句话说,这两个任务必须彼此了解,并且必须以某种方式执行,这取决于另一个.在雾情况下,这意味着一个人在另一个人完成之前无法开始.异步意味着它们是完全独立的,并且在启动或执行中都不得以任何方式考虑对方. (3认同)
  • 异步不会自动转换为在另一个线程上执行代码.例如,WPF消息泵允许在一个线程上执行异步操作. (3认同)
  • @AdamRobinson,同步/异步与多线程无关。JavaScript是异步的,但仍是单线程的。无论如何,多线程是一种实现异步处理的方法,但不是唯一的一种。 (2认同)
  • (a)同步性根本不与线程有关.我认为这是非常误导的.另请参阅:https://blog.stephencleary.com/2013/11/there-is-no-thread.html (2认同)
  • @DamienRoche 同步的意思是“同时**行**” (2认同)
  • @DamienRoche 你可以怪英国陷阱的陷阱,我的朋友。将 **a** 词与 **anti** 词混淆是很常见的。许多以英语为母语的人也将这些混为一谈也无济于事。根据您提供的同步定义,这里的关键是 **a**synchronous 没有时间概念或尊重,因此它的本质不是同步的。 (2认同)

Cha*_*ana 1098

同步/异步无需多线程.

同步或同步意味着以某种方式"连接"或"依赖".换句话说,两个同步任务必须彼此了解,并且一个任务必须以某种方式执行,这取决于另一个任务,例如等待启动直到另一个任务完成.
异步意味着它们是完全独立的,无论是在启动还是执行中,都不能以任何方式考虑对方.

同步(一个线程):

1 thread ->   |<---A---->||<----B---------->||<------C----->|
Run Code Online (Sandbox Code Playgroud)

同步(多线程):

thread A -> |<---A---->|   
                        \  
thread B ------------>   ->|<----B---------->|   
                                              \   
thread C ---------------------------------->   ->|<------C----->| 
Run Code Online (Sandbox Code Playgroud)

异步(一个线程):

         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-->| 
Run Code Online (Sandbox Code Playgroud)

异步(多线程):

 thread A ->     |<---A---->|
 thread B ----->     |<----B---------->| 
 thread C --------->     |<------C--------->|
Run Code Online (Sandbox Code Playgroud)
  • 启动和任务A的结束点,B,C表示通过<,>字符.
  • 由垂直条表示的CPU时间片 |

从技术上讲,同步/异步的概念实际上与线程没有任何关系.虽然通常情况下,发现在同一个线程上运行的异步任务是不寻常的,但有可能(参见下面的示例)并且通常会发现两个或多个任务在不同的线程上同步执行...不,这个概念同步/异步需要在另一个(第一)任务完成之前是否可以启动第二个或后续任务,或者它是否必须等待.就这些.什么线程(或线程),进程或CPU,或者实际上,执行任务的硬件是什么并不重要.实际上,为了说明这一点,我已经编辑了图形以显示这一点.

异步的例子.在解决许多工程问题时,该软件旨在将整个问题分解为多个单独的任务,然后异步执行.反转矩阵或有限元分析问题就是很好的例子.在计算中,排序列表就是一个例子.例如,快速排序例程将列表拆分为两个列表,并通过递归调用自身对每个列表进行排序.在上面的两个例子中,两个任务可以(并且经常是)异步执行.它们不需要在单独的线程上.即使是具有一个CPU的机器,也只有一个执行线程可以编码,以便在第一个任务完成之前启动第二个任务的处理.唯一的标准是一个任务的结果不必作为另一个任务的输入.只要任务的开始和结束时间重叠,(只有当两者的输出都不需要作为另一个的输入时),它们才会异步执行,无论使用多少线程.

同步示例.任何由多个任务组成的进程,其中任务必须按顺序执行,但必须在另一台机器上执行(获取和/或更新数据,从金融服务获取股票报价等).如果它位于单独的机器上,则它位于单独的线程上,无论是同步还是异步.

  • 为什么世界上的单词在计算机中意味着不同的东西...总是让我回到这个...从字典..同步:**同时发生.**异步:**不同时发生** (85认同)
  • 但正如你在计算机中看到的那样,它意味着相反 (15认同)
  • @MuhammadUmer:在计算机世界中,同时发生的被称为并发. (11认同)
  • 也许命名法是基于任务的启动是否与其他任务的完成"同步"? (5认同)
  • 恕我直言,这些图片并不都描述任务的同步和非同步执行.例如,第二张图片暗示异步任务需要多个线程.实际上,它没有.而且这些任务必须并行运行,这也不是必需的.或者,"同步"的图片很好地显示了如何从某个调用站点异步调度任务,现在在串行任务调度程序中执行;)IMO,这些图片具有误导性. (5认同)
  • 实际上,对于CouchDeveloper,该图完全不暗示线程。它只是暗示或表示,当多个任务异步执行时,第二个及后续任务可以在之前的任务完成之前开始,而当它们同步执行时,它们必须等待直到所有先前的任务完成为止。不管它们是在不同线程(或不同进程)上,在同一台计算机上,在不同计算机上还是在同一台CPU上的同一线程上,线程在一个任务与另一个任务之间不断切换都是无关紧要的。 (2认同)
  • @Mandroid,当然,看看在8086或8088处理器上运行的早期Unix操作系统.他们只有一个CPU,因此,根据定义,他们只有一个物理线程,但它是一个多处理操作系统.(虽然在OS代码中,它创建了多个"逻辑"线程来组织他们正在执行的多个任务.)但即使只在一个逻辑线程上,我也可以编写一个程序程序,该程序散布指令以执行一个任务与执行的其他指令第二项任务 - 即使是与第一项完全无关的任务. (2认同)
  • @Mandroid,一个常见的例子是递归工程问题,如反转矩阵或有限元分析问题.在这些软件算法中,整个例程将问题分成多个较小的部分,每个部分可以独立于其他部分解决.整个例程以重叠方式设置,启动和执行多个部分,如上面标有*Asynchronous(一个线程)*的图表.有时必须将结果组合起来以生成过程的整体结果,有时不会. (2认同)
  • @Mandroid:一个典型的例子可能是python中的"线程"(`threading`包).它们允许您在给定的_interval_中同时__-工作,可以在多个任务上进行.但是在给定的_instant_及时,实际上只有一个任务被操作(所以你不能利用多个CPU).这里的关键思想是"可中断性" - 当一个线程在另一个线程上执行时,可以暂停工作.在Python中用于I/O绑定任务但不是CPU绑定任务. (2认同)
  • 我们这里的大多数人(包括我自己)可能在视觉上更好地理解事物,因此对于 ASCII 艺术图表 +1 :D (2认同)
  • 不。将术语“同步/异步”或“单线程/多线程”应用于编程语言是愚蠢的。您可以用任何语言编写将在这四种模式中的任何一种中执行的软件算法(取决于其执行的操作系统和硬件)。 (2认同)

the*_*ien 614

简单来说:

同步

你在队列中获得电影票.在你面前的每个人得到一个之前你不能得到一个,这同样适用于排在你后面的人.

异步

你和许多其他人在一家餐馆.你点了食物.其他人也可以订购他们的食物,他们没有必要等待你的食物烹饪,并在他们订购之前送达你.在厨房餐厅工作人员不断烹饪,服务和接受订单.一旦煮熟,人们就会得到他们的食物.

  • 如果有人想要苹果而不是苹果; 如果你想让餐厅的情况同步,那么当你点菜时,餐馆里的其他人都必须等到你的食物才能到达他们的食物等等.现在这似乎是一个非常愚蠢的场景,但在计算机领域,这种情况可能很有用.假设每个客户都无法决定他们想要什么,而是想看看之前的客户订单决定他们是否需要,那么他们必须在订购之前等待食物到达. (10认同)
  • 非常简单和真实的例子 (4认同)
  • 为了进一步推动您的示例,他们可以考虑使用多个售票口。因此,每条线可以与另一条线异步工作,但在其内部同步工作! (4认同)

BKS*_*eon 310

通过类比简单解释

同步执行

我的老板是一个忙碌的人.他告诉我写代码.我告诉他:好的.我开始了,他正像一只秃鹰一样看着我,站在我身后,从我肩膀上.我喜欢"伙计,WTF:你为什么不去做我做完这件事呢?"

他就像是:"不,我在这儿等,直到你完成." 这是同步的.

异步执行

老板告诉我这样做,而不是在那里等待我的工作,老板去做其他任务.当我完成工作后,我只是向老板报告说:"我做完了!" 这是异步执行.

(听从我的建议:永远不要和你身后的老板一起工作.)

  • 我做完了...当你把这当作辞职时,它甚至更有趣. (26认同)
  • 每次“一只手”进行“同步”工作。一次用“两只手”进行“异步”工作。 (2认同)
  • @GrayProgrammerz ...明确地说:`同步`:你可以有两只手,但第二只手必须在第一只手完成后才能工作。 (2认同)

Ree*_*sey 88

同步执行意味着执行在一个系列中发生. A->B->C->D.如果你正在调用这些例程,A将运行,然后完成,然后B将启动,然后完成,然后C将启动,等等.

使用异步执行,你开始一个例程,让它在你开始下一个时在后台运行,然后在某个时候,说"等待这个完成".它更像是:

开始 A->B->C->D->等待用于A完成

其优点是可以执行的B,C和或D同时A仍在运行(在后台运行,在单独的线程),所以你可以把你的资源更好的优势,有较少的"挂起"或"等待".

  • @Devrath操作可以按任何顺序完成. (8认同)

Rag*_*czy 54

同步意味着调用者等待响应或完成,异步调用者继续并且响应稍后(如果适用).

举个例子:

    static void Main(string[] args)
    {
        Console.WriteLine("Before call");
        doSomething();
        Console.WriteLine("After call");
    }

    private static void doSomething()
    {
        Console.WriteLine("In call");
    }
Run Code Online (Sandbox Code Playgroud)

这将始终输出:

Before call
In call
After call
Run Code Online (Sandbox Code Playgroud)

但是,如果我们要使doSomething异步(多种方式),那么输出可能变为:

Before call
After call
In call
Run Code Online (Sandbox Code Playgroud)

因为进行异步调用的方法会立即继续下一行代码.我说"可能",因为使用异步操作无法保证执行顺序.它也可以作为原始执行,具体取决于线程时间等.


ent*_*3te 54

简而言之,同步是指两个或多个进程的起点终点,而不是它们的执行.在此示例中,进程A的端点与进程B的起始点同步:

SYNCHRONOUS
   |--------A--------|
                     |--------B--------|

异步进程,而另一方面,也不能有自己的起点和终点同步:

ASYNCHRONOUS
   |--------A--------|
         |--------B--------|

在进程A与进程B重叠的情况下,它们同时或同步运行(字典定义),因此产生混淆.

更新:Charles Bretana改进了他的答案,所以这个答案现在只是一个简单的(可能过于简化的)助记符.

  • Charles Bretana的副本回答 (2认同)
  • @DineshSaini - 我的图略有不同.为清楚起见,我在两种情况下都将A放在B的顶部,强调它们的起点和终点是否同步.Charles Bretana的图表按顺序放置了同步过程而没有"同步"任何东西.(我将在下面评论他"改进"它的答案,但意识到显示新图表会更容易.) (2认同)

aJ.*_*aJ. 33

我认为这是有点圆的解释,但它仍然澄清使用现实生活中的例子.

小例子:

假设播放音频涉及三个步骤:

  1. 从硬盘获取压缩的歌曲
  2. 解压缩音频.
  3. 播放未压缩的音频.

如果您的音频播放器按顺序为每首歌曲执行步骤1,2,3,则它是同步的.您将不得不等待一段时间才能听到这首歌,直到该歌曲实际被取出并解压缩.

如果您的音频播放器执行步骤1,2,3彼此独立,那么它是异步的.即.在播放音频1(步骤3)时,如果它并行地从硬盘中取出音频3(步骤1)并且它并行地解压缩音频2.(步骤2)你最终会听到这首歌,而无需等待获取和解压缩.


yoA*_*ex5 24

同步编程模型 - 将线程分配给一个任务并开始处理它.任务完成后,它可用于下一个任务.在这个模型中,它不能让执行任务处于中间以承担另一个任务.让我们讨论一下这个模型在单线程和多线程环境中的工作原理.

单线程 - 如果我们要处理几个任务并且当前系统只提供一个线程,那么任务将逐个分配给线程.它可以用图形描绘为
同步单螺纹

多线程 - 在这种环境中,我们曾经有多个线程可以处理这些任务并开始研究它.这意味着我们有一个线程池(也可以根据需求和可用资源创建新线程)和一堆任务.所以这些线程可以在这些上工作
同步多线程

异步编程模型 - 与同步编程模型相反,这里一个线程一旦开始执行一个任务就可以将它保存在中间,保存当前状态并开始执行另一个任务.

单螺纹 异步单线程

多线程 异步多线程

更多信息,请访问https://codewala.net/2015/07/29/concurrency-vs-multi-threading-vs-asynchronous-programming-explained/


Mic*_*ski 23

简单地说异步执行就是在后台做事.

例如,如果要从Internet下载文件,可以使用同步函数来执行此操作,但它会阻止您的线程,直到文件完成下载.这可能会使您的应用程序无法响应任何用户输入.

相反,您可以使用异步方法在后台下载该文件.在这种情况下,下载功能立即返回,程序执行正常继续.所有下载操作都在后台完成,程序完成后会通知您.

  • 它没有更快.这是关于不阻塞主线程,以便它可以处理其他类型的用户输入.例如,用户可能想要取消下载或同时开始下载另一个文件. (4认同)
  • 你的例子怎么样会更快。最后,在下载完成之前,您无法播放该文件。你可以解释吗?我想我当时不理解异步,可能是我,但是当其他进程正在运行(获取下载)时,其他步骤或进程会做什么?我的意思是,在您的应用程序中收到异步进程(下载)之前您可以做什么......我不明白。那么,无论在哪种情况下,您仍然必须向用户展示某种等待机制? (2认同)

Das*_*tha 15

作为一个非常简单的例子,

同步

想象一下,10名学生被指示在路上排队等候.

第三个学生解开了她的鞋带.现在她已经停止并再次绑起来.

她身后的所有学生都已经停了下来,现在正等着她把它绑起来.第一和第二名学生已经走过所有人,并继续按照他们的平常步伐.

1------>
        2.
                3.
Run Code Online (Sandbox Code Playgroud)

异步

想象一下10个随机的人走在同一条路上.他们当然不在队列中,只是随意地以不同的步伐在路上的不同地方行走.

第三人的鞋带解开了.她停下来再把它绑起来.

但是没有人在等她把它捆绑起来.其他人仍然以他们以前的方式行走,与他们同样的步伐.

      1.
        2------>
                3.
Run Code Online (Sandbox Code Playgroud)


小智 14

执行如下序列时:a> b> c> d>,如果我们在执行过程中遇到失败,例如:

a
b
c
fail
Run Code Online (Sandbox Code Playgroud)

然后我们从头开始重新开始:

a
b
c
d
Run Code Online (Sandbox Code Playgroud)

这是同步的

但是,如果我们执行相同的序列:a> b> c> d>,我们在中间失败:

a
b
c
fail
Run Code Online (Sandbox Code Playgroud)

...但是我们不是从头重新开始,而是从故障点重新开始:

c
d
Run Code Online (Sandbox Code Playgroud)

......这被称为异步.

  • 这个答案根本不正确. (5认同)

Abo*_*ian 13

我创建了一个gif来解释这一点,希望对您有所帮助:外观,第3行是异步的,其他行是同步的。第3行之前的所有行都应等待,直到第3行完成工作为止,但是由于第3行是异步的,因此下一行(第4行)不要等待第3行,而第5行则应等待第4行完成其工作,第6行应等待第5行和第7行等待6行,因为第4、5、6、7行不是异步的。 第3行是异步的,其他是同步的


小智 7

您将Synchronous与Parallel vs Series混淆.同步意味着所有的同时.同步化意味着与每个领域相关,这可以意味着串联或以固定间隔.虽然程序正在全力以赴,但它是串行运行的.得到一本字典......这就是为什么我们有不甜的茶.你有茶或加糖茶.

  • 同步*不*意味着计算中的“全部同时”。您混淆了同步与同步,以及“并行与串行”与茶和甜茶。答案毫无意义。 (4认同)
  • 实际上,"同步"是指指令和时钟之间的关系.不是指令本身之间的关系.这就是为什么它向后看"同步"实际上意味着一个又一个:但是指令与时钟同步."异步"意味着"在任何时候,我都不关心它何时发生":指令不需要与时钟同步.是的,有字典定义,但您必须确保定义正确的情况. (3认同)

小智 6

同步基本上意味着你一次只能执行一件事.异步意味着您可以一次执行多个操作,并且您不必完成当前操作即可继续执行下一个操作.


Max*_*eev 5

同步操作在返回调用者之前完成其工作。

异步操作在返回到调用者后执行(大部分或全部)工作。


Hla*_*Swe 5

使用说明做早餐的例子

  1. 倒一杯咖啡。
  2. 加热锅,然后煎两个鸡蛋。
  3. 炒三片培根。
  4. 吐司两片面包。
  5. 在烤面包上加黄油和果酱。
  6. 倒一杯橙汁。

如果您有烹饪经验,则可以异步执行这些指令。您将开始加热锅中的鸡蛋,然后开始培根。您将面包放进烤面包机,然后开始放鸡蛋。在该过程的每个步骤中,您都将开始一个任务,然后将注意力转移到可以引起注意的任务上。

做早餐是一个很好的例子,说明异步工作不是并行的。一个人(或线程)可以处理所有这些任务。继续进行早餐类比,一个人可以通过在第一个任务完成之前启动下一个任务来异步制作早餐。无论有人在看菜,烹饪都会进行。一旦开始加热锅中的鸡蛋,就可以开始煎培根了。培根开始后,就可以将面包放进烤面包机了。

对于并行算法,您需要多个库克(或线程)。一个人做鸡蛋,一个人做培根,依此类推。每个人只会专注于一项任务。每个厨师(或线程)将被同步阻止,以等待培根准备翻转或吐司吐司。

异步编程概念的参考