对 Kotlin 与协程相关的挂起函数感到困惑

Bel*_*gor 6 kotlin kotlin-coroutines

如果我理解正确的话,挂起函数是您可以在协程内执行的函数,挂起函数的作用是挂起协程,以便另一个协程可以开始工作。现在,这是否意味着当协程挂起时,挂起函数仍在工作?这让我感到困惑,因为我看到很多文本都说它不仅暂停协程,还暂停暂停函数。但是,如果它也暂停了挂起功能,那么如果您想要完成的工作暂停了,那还有什么意义呢?

假设我有一个挂起函数,需要 30 秒才能完成一些数学计算。然后我有另一个协程,它打印了一些简单的文本,例如“Hello,World”。如果第一个协程挂起并转到第二个协程打印问候语,数学计算还会同时进行吗?

Mar*_*nik 6

现在,这是否意味着当协程挂起时,挂起函数仍在工作?

不,这意味着当它被挂起时,其他功能可以工作。

这让我感到困惑,因为我看到很多文本都说它不仅暂停协程,还暂停暂停函数。

这是对的。

但是,如果它也暂停了挂起功能,那么如果您想要完成的工作暂停了,那还有什么意义呢?

主要用例是将工作委托给外部资源,尤其是网络层。当您的函数正在等待来自网络的数据时,它没有其他事情可做。与此同时,其他协程可能会继续在同一线程上执行。

假设我有一个挂起函数,需要 30 秒才能完成一些数学计算。

该函数尽管被声明为可挂起,但实际上可能不会自行挂起。它会继续占用调用线程。

然后我有另一个协程,它打印了一些简单的文本,例如“Hello,World”。

如果您使用的是单线程调度程序,则该协程必须等待轮到第一个协程显式挂起自身,这可能不会在您提到的 CPU 密集型函数中发生。

如果第一个协程挂起并转到第二个协程打印问候语,数学计算还会同时进行吗?

不,挂起的协程不执行任何工作。

例如,第一个协程可以yield()在其计算循环内调用,从而允许 Kotlin 挂起它并在同一线程上运行一些其他协程。暂停期间不会取得任何进展。

您可以这样看:假设有一个线程运行所有协程。它们运行的​​方式称为协作并发。协程必须显式挂起自身以允许其他协程运行。这与在单个 CPU 核心上同时运行的多个线程非常相似,只不过操作系统可以做另一件“神奇”的事情:它可以随时挂起线程,而无需该线程的许可。这就是为什么这种被称为抢占式并发