一个 cpp 协程库的前世今生(一)缘起
背景
撸一个协程库是我的一个夙愿,从大学知道有协程这么个东西之后就想自己写一个,所以并不是说现在开源的协程不满足我的需求,而是纯粹想体验一下从头开始设计开发会遇到什么困难,而我又能从中学到什么。
我想做成什么样子
我心目中的协程库,是想 golang 实现的那样带有调度器的广义的协程,我心目中的协程库应该需要以下特性:
接口简单
这个方面 Go 可以说是做到了极致,一个
go
关键字就可以启动一个 goroutine。但是对我来说,他可能有些太精简了,以至于创建之后我们就失去了对 goroutine 的控制,无法获取他的权限,无法获取函数的返回值等(当然通过一些手段也是可以做到的)。所以我所说的接口简单,是在创建一个协程不需要填一堆参数的前提下,还能返回一个协程对象供我们了解协程的状态,并对其做一些控制等。灵活迁移
众所周知,协程是比线程更低一级的调度单元,因此一个协程的运行总是需要在线程上下文中(毕竟操作系统只认识线程)。但是这样就会面临一个工作服在无法均衡的问题。举个例子,一开始有 T1、T2 两个线程,T1 下有 C1、C2 两个协程在调度,T2 下有 C3、C4 两个协程在调度,运行一段时间后,T1 下的协程都完成了,但是 T2 下面仍然有两个协程在不停调度,这就会导致工作量不均衡的问题。如果协程可以在不同的线程间迁移,这个问题就可以得到缓解。
外部调度
如上文所述,协程是依赖于线程的,运行在线程的上下文中,因此。如果协程中有死循环或者长时间的操作,就会导致线程发生阻塞,进而影响到当前线程下其他的协程调度(上面提到的协程迁移可以解决部分问题,但是不是完美的解决方案)。因此,需要一种可以从外部干涉调度的手段,强制将长时间占用 CPU 资源的协程切换出去。
同步手段
和线程一样,协程作为一种高并发的解决方案,协程间同步的手段一定必不可少,互斥锁、信号量、条件变量、读写锁等。
其他
其他的一些小细节,如 channel、协程优先级、共享栈、协程局部存储等。
0.1.0 版本
目前已经完成了基本的版本,位于:https://github.com/skyfireitdiy/cocpp/tree/cocpp-0.1.0
在后续的章节中,我会逐步介绍其中每个模块的设计与实现,希望读者可以通过本系列文章学习到一些知识,也渴望从交流中不断充实自己。
版权声明: 本文为 InfoQ 作者【SkyFire】的原创文章。
原文链接:【http://xie.infoq.cn/article/06650f12b79d865fb1bddf491】。文章转载请联系作者。
评论