协程

协程

中文名 协程
目录导航

历史

协程的概念最早由Melvin Conway在1963年提出并实现,用于简化COBOL编译器的词法和句法分析器间的协作,当时他对协程的描述是“行为与主程序相似的子例程”。

 

1980年Marlin的论文中给出的定义类似,也是被广为引用的协程定义:

•协程的本地数据在后续调用中始终保持

•协程在控制离开时暂停执行,当控制再次进入时只能从离开的位置继续执行

 

直到2004年由Lua的作者Ana Lucia de MouraRoberto Ierusalimschy所发表的论文《Revisiting Coroutines》中,才正式对协程进行了分类,论文中依照三个问题区分协程:

•控制传递(Control-transfer)机制

•协程是否作为语言的第一类(First-class)对象提供

•协程是否为栈式(Stackful)构造,即是否可以在内部的嵌套调用中挂起

 

       协程本质是一种控制抽象,它的价值在于可以简洁优雅地实现一些控制行为。在协程中,控制可以从当前执行上下文跳转到程序的其它位置,并且可以在之后的任意时刻恢复当前执行上下文,控制从跳出点处继续执行。这种行为与Continuation类似,但协程相比之下更容易理解,某些情况下还更加高效

 

       协程还适于实现状态机(每对入口/出口点表现一个状态),参与者模型(Actor model)(实质上也是协作式多任务)等。重要的是理解协程所表达的控制抽象,在此之上能够灵活运用的话,原本一些棘手的控制问题也许就可以简洁优雅地实现出来。

 

       如今对协程的研究和应用有重新复苏的趋势,主要集中在两个方向。一个是研究它在协作式多任务管理上相对于多线程的优势,目前以程序库和系统资源的方式提供了一些此类协程。另一个就是用于迭代器和生成器的协程,如Perl、C#、Python等。而Lua基于Revisiting Coroutines的观点,实现了完全非对称协,事实也证明了这种机制在实现一些控制结构时异常方便和强大。

Lua示例

编程语言Lua从5.0版开始支持协程的概念,极大的扩展了Lua的能力。Lua的协程通过扩展库coroutine来实现,其中的所有函数如下(具体可以参考Lua的官方manual)

1

2

3

4

5

6

coroutine.create

coroutine.resume

coroutine.running

coroutine.status

coroutine.wrap

coroutine.yield

当前运行的代码可以看作运行在主协程中(就像C程序的main运行在主线程中),通过create可以创建一个协程,resume以运行此协程,直到新协程调用yield程序才能返回到”主协程“中运行。

coroutine.creat()

函数参数:接收单个参数,该参数是coroutine的主函数,即resume会执行的函数

函数返回值:返回其控制器,一个对象为thread的对象

函数作用:creat函数创建一个新的coroutine,定义了协程内的任务流程。从面对对象的角度来看,可以看成是coroutine类创建了一个对象co

coroutine.resume(co,[val1,val2,...])

函数参数:第一个参数即creat的返回值,一个thread对象。第二个参数是coroutine中执行需要的参数,是一个变长参数,可以传入任意多个。

函数返回值:当程序运行没有错误的时候,返回true,同时返回前一个调用coroutine.yield中传入的参数。如果有错误,返回错误false以及错误信息。

函数作用:当第一次嗲用coroutine的resume方法的时候,其从主函数第一行开始执行,之后再coroutine开始运行后,它会一直运行到自身终止或者是coroutine的下一个yield函数。

coroutine.yield(...)

函数参数:传入变长参数

函数返回值:返回在前一个resume中传入的参数值

函数作用:挂起当前的执行协程。该协程不能是一个C函数,一个元表或一个迭代器

coroutine.running():返回当前正在执行的协程

coroutine.status():返回当前协程的状态,有running/suspended/normal/dead等。

相关百科
返回顶部
产品求购 求购