协同程序只是完成处理程序周围的语法糖吗?

时间:2017-09-12 10:34:16

标签: asynchronous async-await kotlin coroutine

协同程序是否只是完成块周围的语法糖和完成块将在引擎盖下创建?或者协同程序的概念要复杂得多,而且只是编译技巧,即语法糖

4 个答案:

答案 0 :(得分:4)

这不仅仅是语法糖,根本不是。协程不阻止线程,只是暂停执行,因此他们鼓励非阻塞并发编程。

协同程序不依赖于操作系统或JVM的功能(例如,它们未映射到本机线程)。相反,协同程序和suspend函数特别是由编译器转换,生成一个状态机,能够处理一般的暂停,并传递挂起的协同程序保持其状态。这是由 Continuations 启用的,它们作为参数添加到编译器的每个挂起函数中;这种技术被称为“延续传递风格”。

有关详细信息,请查看https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md

答案 1 :(得分:2)

不,协同程序不是语法糖。您可以将协同程序视为可以与调用者交互的函数。当您调用普通函数时,请说foo将控制权传递给foo,并且必须等到foo完成或抛出异常。协同程序是可以将控制权传递给调用者的函数,调用程序可以决定协程是否应该继续,何时如何协程应该继续。这为在其他语言中实现特殊语言结构的东西提供了机会:

  • 生成器(又名yield关键字),如C#和JavaScript。当用户想要来自迭代器的新值时,调用者继续执行协同程序。 Coroutine通过调用yield()函数传回调用者,该函数也将一些值传递给调用者。
  • 异步/等待在C#和JavaScript中。当Future(类似于Task或Promise)得到解决时,调用者继续执行。 Coroutine通过调用await()函数传回调用者。当Future得到解决后,调用者将值传递给协同程序,并且协程会在await()调用后观察到此值。
  • Go的Goroutines /频道。

与C#,JavaScript或Go不同,Kotlin没有在特殊语法中实现任何这些功能。相反,Kotlin只提供suspend fun语法,然后您可以自己实现这些功能(或从相应的库中获取现有的一个名为kotlinx.coroutines)。

答案 2 :(得分:0)

我建议你听听Chris Lattner(Swift的创建者)讲述未来的Swift Concurrency模型。 链接:https://spec.fm/podcasts/swift-unwrapped/84323

在11:30他说:

  

您可以将async / await视为完成处理程序周围的语法糖

答案 3 :(得分:0)

Corutines是围绕异步过程的语法糖,或更准确地说,Actor是可重复的异步过程。