浅谈协程
协程(coroutine)是一种程序组件,一个轻量级的线程.在单核CPU中系统会将CPU划分为时间片,调度不同线程进行运行,给用户造成所有程序在同时运行的错觉;在多核CPU中每个线程可能由不同的CPU来执行.但是协程单核CPU和多核CPU中都和单核CPU中线程一样.协程在状态机,角色模型,迭代器,产生器非常实用.在网上看了好多协程的介绍和例子,总结下.
协程实现的语言不是很多,lua是其中之一
1)lua中操作协程的函数:
coroutine.create() --创建一个协程
coroutine.yield() --挂起一个协程
coroutine.resume() --唤醒一个协程
lua中协程中通过yield和resume进行信息交换
resume中第一个参数是create函数的返回值即创建的协程句柄,后面参数是我们需要传递给yield的值,由于默认状况下协程是挂起的,因此第一次唤醒协程时,我们传入的第一个后面的参数均是作为create函数中匿名函数的参数.
resume的返回值第一个参数表示协程的执行状态,后面的值是有yield传递的.
yield传递的参数是resume时的返回值,yield的返回值是resume时的参数(除了第一次调用).
我们通过一个程序可以很容易理解协程工作原理.
输出:
val : 1 2
main : true 3
x : 4
main : true 8
s : This is coroutine.
main : true
main : false
main : true 3
x : 4
main : true 8
s : This is coroutine.
main : true
main : false
我们现在用协程实现一个经典的生产者和消费者问题(由消费者驱动),
2)python中也支持协程,python中把它当做generator.python中提供了yield关键字,我们同样以生产者消费者模式来介绍.
示例:
python中如果一个函数含有yield关键字,就被视为generator, generator默认具有next(), send(), close()方法, send和next都可以唤醒协程从上一个yield地方开始执行,但send可以传递参数作为yield返回值.
3)在wiki链接中提到了协程的经典实现中有个C语言实现的,看到这个实现原理让我吃了一惊,原来C语言可以在switch中嵌套循环.同时boost1.53.0也加入了协程库,并配置了处理网络的例子(其实boost在1.53.0之前的asio库中http例子中也实现了简单的协程就是用到了前面C语言经典实现的原理书写的).