Programming Language: Concept: Coroutine

 8th November 2022 at 11:43am

Coroutine,以及中文的「协程」,是与 thread(线程)相对应的一个词。

线程是抢占式的(preemptive),它是基于 OS 将 CPU 资源切分成时间片,在每个时间片内选择一个线程来运行。时间片一到,运行权被 OS 回收,重新调度。

Coroutine 的意思是 cooperative function。它与线程类似的地方在于,它也有调用栈和局部变量,也可以使用全局变量。但是它不是抢占式的。一个协程通过 yield 让出其控制权,使得调度器(编程语言所实现,而不是 OS 所实现)可以将运行权交给另外一个协程。

当然运行协程的仍然是线程。只是从编程模型上看,使用协程来做协作的粒度更小。编程语言的协程实现中,可以用一个或者多个线程来实现整套调度和运行

协程的好处

  • 实现了 async / await 模型(可能不够准确),使得 可以用同步方式写异步代码
  • 非常轻量,没有线程那么重的 context switching 和内存消耗
  • 减少了对锁的需要,增加了系统资源利用率

中文语境中的「协程」,稍微有一些需要注意的点:

  • 对于 Python 及 Lua,协程的含义和实现与上文描述一致
  • 对于 Go,其「协程」名为 goroutine,并不是真正的 “协” 程,因为它是抢占式的

对称与非对称性

Coroutine 的实现有两种:

  • 非对称的(asymmetric):也称半对称的(semi-symmetric),表示协程实现的 API 中,即有调用协程的 API,也有 将控制权交还给调用者的 API(比如 Python 及 Lua 的 yield)。这种实现中,这两个协程的关系像是普通函数一样,有调用方和被调方
  • 对称的(symmetric):这种实现中 没有 将控制权交还给调用者的 API。协程间没有调用关系。没有用过这种实现的协程,感觉缺少方便性。

参考: