Coroutine介绍

发布于:2021-10-23 08:24:42

今天看了云风的blog里面写到了一个片段:“我们采用的是大量进程(非 OS进程,这里指 Erlang进程)协作工作的模式。”大体思考了一下,他们用c+lua开发,这里指的Erlang进程,大概指的是采用了与Erlang相似的“协程”方式。于是顺便了解了一下协程的概念和最简单的实现。


coroutines是一个古老的计算模式,中文翻译叫“协程”,在现代程序语言里面属于“非主流”,erlang语言底层就是采用的这种模式实现的。


???????? coroutine和subroutine(子程)的不同点在于coroutine可以很多个调用入口点,而subroutine只能有一个。当coroutine被第一次调用到的时候,它将从起始处开始执行,一旦遇到具有yield(类似subroutine中的return语句)语义的语句的时候,就是返回给另外一个coroutine或者调用者,而在接下来再次被调用的时候,就从yield语句下面的一条语句继续执行直到遇到新的yield语句或者coroutine的结束。


对于subroutine调用方式已根深蒂固的开发者说,上面的coroutine介绍肯定是非常抽象和空洞的,下面就通一个使用C语言实现的一个非常简单的coroutine程序来具体化这个概念:


注:最开始读这种方式比较吃力,进行跟踪之后才大体理清楚了执行过程,读懂这些有助于了解“协程”这一概念。



#include


using namespace std;


intswitch_magic(void){


??? static int i, state =0;


??? cout<<"State:"<

??? switch(state){


??? case 0: // start offunction


?????? for(i = 0; i < 10; i++){


?????????? state= 1; // so we will come back to "case 1"


?????????? cout<<"I:"<

?????????? return i; // resume controlstraight after the return


??? case 1:


?????? cout<<"what?"<

}


??? }


??? return -1;


}


int main(){


??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? cout<

??? getchar();


??? return 0;


}





运行输出:


0
1
2
3
4
5
6
7
8
9
-1








通过定义一些精巧的macro可以屏蔽coroutine的C实现细节,让代码更加简单、易读:





#include ??


using namespace std;??


#define crBegin?static ?int?state=0;switch(state) {?case 0:??


#define?crReturn(x) ?do { state=__LINE__; ?return x;


???????????????????? ?case__LINE__:; }while (0)??


#define ?crFinish }??


int ?switch_magic(void) {


??? static int i;


??? crBegin


?????? for (i = 0; i < 10; i++)


?????????? crReturn(i);


??? crFinish


?????? return -1;


}??


?


int main(){????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? cout<< switch_magic() << endl;????


??? return 0;


}





相关推荐

最新更新

猜你喜欢