实践 Go 团队主要成员的一个协程草案
去年的时候,我看到了 Russ Cox 的一篇文章 research!rsc: Coroutines for Go (swtch.com)。对 Go 团队成员比较熟悉的的朋友应该知道,这是个老面孔了。这篇文章呢,是一个在go中添加协程的草案。注意,此协程 coroutine 非彼协程 goroutine。
阅读之后,感觉挺有意思。简单来说,这个协程通过无并行性提供并发:当一个协程运行时,恢复或让给它的那个协程或线程都没有并行执行。
什么意思呢,我们熟悉的 goroutine 其实更接近线程,不同线程之间完全可以并行执行。但是协程不一样。虽然多个协程可以同时发生(并发),但是同一时间只能有一个在执行。就像接力棒一样,甲和乙可以同时参加比赛,但队伍里是总是一个人在跑,多人通过接力棒接替着跑。
这体现了协程协作的本意。
显然 coroutine 比 goroutine 有了更多的限制,有失就有得。coroutine 切换最多只需要大约十纳秒,而 goroutine切换接近于几百纳秒。因为 goroutine 需要 runtime 介入调度,而 coroutine 的调度是显式的,也就是明确说了,接下让谁执行(接力棒给谁),几乎没有调度开销。
目前这个草案还没正式成为提案,不过 Russ Cox 已经给出了一个粗糙的实现(基于泛型)。这里不得不插一句,如果没有泛型,恐怕需要黑魔法才能搞出这么一个实现来。
虽然这个粗糙实现底层还是 goroutine,也就是不能带来性能上的优势。但还是解决了我如何实现中断和恢复机制的问题。在 ograph 中,我想实现的中断恢复就是引擎代码和用户代码可以交替执行,也有点类似于内核态和用户态的切换。
感兴趣的朋友可以看下 ograph/coro/coro.go at main · symphony09/ograph (github.com)。
草案地址:research!rsc: Coroutines for Go (swtch.com)。
英语不太好的朋友,也可以看下我的翻译:Coroutines for Go -1 | 年鲤的博客 (symphony09.github.io)。
本作品采用《CC 协议》,转载必须注明作者和本文链接
并行没有什么意义