2.2.2 按调度方式分类

调度过程中,根据协程调度权的转移目标的不同又可将协程分为对称协程非对称协程

·对称协程(Symmetric Coroutine):任何一个协程都是相互独立且平等的,调度权可以在任意协程之间转移。

·非对称协程(Asymmetric Coroutine):协程出让调度权的目标只能是它的调用者,即协程之间存在调用和被调用关系。

对称协程实际上已经非常接近线程的样子了,例如Go语言中的go routine可以通过读写不同的channel来实现控制权的自由转移,而非对称协程的调用关系实际上更符合我们的思维方式。常见语言对协程的实现大多是非对称实现,例如Lua的协程中,当前协程调用yield总是会将调度权转移给之前调用它的协程(参见2.3.2节);还有我们在前面提到的async/await,await时将调度权转移到异步调用中,异步调用返回结果或抛出异常时总是将调度权转移回await的位置。

从实现的角度来讲,非对称协程的实现更自然,也相对容易,而我们只要对非对称协程稍作修改,即可实现对称协程的能力。在非对称协程的基础上,我们只需要添加一个中立的第三方作为协程调度权的分发中心,所有的协程在挂起时都将调度权转移给分发中心,分发中心根据参数来决定将调度权转移给哪个协程,例如Lua的第三方库coro(http://luapower.com/coro)和Kotlin协程框架中基于Channel(https://kotlinlang.org/docs/reference/coroutines/channels.html)的通信等。