谁负责协程的暂停和继续?

时间:2019-05-24 08:55:17

标签: asynchronous kotlin coroutine kotlin-coroutines

就异步编程而言,这可能是一个非常基本的问题,但我尝试阅读有关该内容的信息,但找不到相同的任何资源。

假设:通常,关于异步编程,我的想法是

  

当我们开始阻塞操作(网络调用,从数据库/文件读取)时,我们可以将其委派给内核线程,这将使我们的应用程序线程可用于其他作业。内核线程等待作业完成,并在作业完成时向应用程序线程提供回调。

协程:最近几天,我一直在阅读有关Kotlin协程的信息。我认为明智的协程在语言上是不可知的。我一直得到的问题是:

suspensioncontinuation对于协同例程如何发生。协程不是线程(操作系统给它分配了处理器的一部分),而是tasks,它们将在要执行的线程上进行调度。

谁一直在寻找正在执行的程序,并说此协程已达到挂起点,应将其从线程中删除。应该在线程上安排需要从continuation恢复的另一个协程。至于我所读过的Java Fibers,将由Fiber Scheduler完成,在Kotlin中是否类似?

谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

协程暂停是完全明确且一流的。当您调用suspendCoroutine()suspendCancellableCoroutine(),并传入一个接收连续性作为参数的块时,就会发生这种情况。

该块可以对延续对象执行任何所需的操作,并且当某人在某个地方调用continuation.resume(resultValue()时,它将恢复。它继续在其上运行的线程最初是调用resume()的线程,但是resume内部的逻辑立即委派给负责的Dispatcher,后者通常将恢复提交给另一个线程或线程池。

Dispatcher逻辑仍然是一流的,您可以编写自己的调度程序。但是,几乎不需要这样做,因为只有少数几种有意义的方法可以做到这一点,而Kotlin已经支持了它们。

您还可以查看concrete example in code,它演示了suspendCoroutinecoroutine.resume()的裸露用法,而没有Dispatcher添加的图层。


顺便说一句,您永远不要将阻塞操作委托给“内核线程”以使它们成为非阻塞的。异步操作不会阻塞任何线程。在较低的级别上,例如有 selector 的机制,该机制在IO操作完成时接收事件。它的工作原理类似于GUI线程中的事件循环。