娱乐
您的位置:主页 > 娱乐 >

c语言实现的协程 - adinosaur

时间:2017-09-05   编辑:admin   点击:102次

这几天陡起地对协程感兴趣,因而我深信不疑一个人,行为准则放在GitHub:

协程是一种用户消失的非捉拿式线索,次要用于处置等丰盛的的IO举动的成绩。

协程vs线索

相反,应用多线索来处置IO闭塞派遣。,应用协程的获得是不必全部地,探望共享履历用不着使时间互相一致举动。。喂较宽容的至于明。,应用协程之因而用不着全部地指责因所大约协程只在一个人线索中运转,另一方面因协程的非捉拿式的加标点于。执意说,应用协程的话,在没主动语态交出CPU在前方都是弱被陡起地切换到其它协程上的。线索是捉拿式的。,应用多线索,您不克不及决定那时线索将由O运转。,那时换?,终于,使负债务应用锁来应验ATO的义素。。

协程vs异步回调

现实上,一个人更遍及和遍及的做法是。,应用非闭塞IO(像异步IO),并且,一套在零碎召集应验异步IO,作为Asio)和回权利转移证书数将处置举动。这种办法通常心不在焉成绩。,纵然当回权利转移证书数抓住更多时,一个人连续的的事情行为准则被散开成多个回权利转移证书数。,高处定期检修本钱。终于应用协程可以用使时间互相一致的笔法写出成功实现的事相当结果异步的行为准则。

应用static变量应验协程

要应验一个人协程,次要成绩是多少容纳作用召集的背景。。我在网上笔记一个人视频博客在前方,协程 in c,为了容纳背景作用以一种非常赞许地简约的办法应验。。行为准则如次:

 1#define crBegin static int _cr_state = 0; switch(_cr_state) { case 0:
 2#define crReturn(x) do { _cr_state = __LINE__; return x; case __LINE__:; } while (0)
 3#define crFinish }
 4 5int func1() {
 6    crBegin
 7while (1)
 8    {
 9         printf("hello world
");
10         crReturn(0);
11    }
12    crFinish    
13 }

此行为准则应用作用的动态变量来容纳作用召集。。留意,因下具有调试效能,因而vs2013的__LINE__的应验指责永恒的终于会波湾阴谋不经过,可以应用GCC波湾阴谋。这段行为准则复杂而复杂,但也在非常成绩。,比方倘若两个协程召集执意同一个人作用,这是误解的。终于,视频博客提到了这段行为准则,次要是给了一个人思绪。,倘若现实应用它一定行不通。。

应用setjmp、longjmp应验协程

我在前方说的,应验协程最次要的是容纳作用的召集的背景,这些背景次要由两做切片结合:1。屈指可数对齐的值,2。作用召集堆栈。在C假释中,你可以经过setjmp容纳作用召集,每个对齐的值。容纳后,便可以经过longjmp重现回到当下setjmp的空间(可以变得流行成跨作用的goto)。纵然,值当留意的是。,setjmp只许诺登记签到容纳的有价值,不许诺定期检修其作用召集栈(为了看一眼setjmp的jmp_buf的安排就已收到),终于,为了作用召集堆栈霉臭由用户手工操作定期检修。。应用setjmp、一个人罕见的误解是,在longjmp,尝试longjmp一个人作用被明智地使用,这时分然而对齐的值是事先容纳的值,纵然召集堆栈不再是起形成作用的人的召集堆栈。。

而我所做的执意,在到达一个人协程的时分在堆上请求一片消失(形成大块为2M)作为协程的召集栈,过后,在setjmp,手工操作更改对齐的值,把它指路我到达的召集堆栈。因而当它运转的时分,为了协程就会应用我预约的那块内存作为栈。

我的为了协程库预约了三个轻摇:

  1. coro_new:到达一个人协程
  2. coro_yield:将把持权汇成给调整协程
  3. coro_main:运转调整协程

协程的把持使泛滥如次:

  1. 经过coro_main运转调整协程,并找出紧邻的人运转的协程,运转之。
  2. 运转为了协程直到其召集coro_yield将把持权免除给调整协程。
  3. 反复由于两个举步,直到拿协程运转抛光。

为了协程库应验的非常赞许地复杂,仅100行行为准则,自然应验它的含义是为了预约一个人最复杂的协程从前的,指责效能整整性、鲁棒性强的能入伙现实事情运转的协程。

因而剧照很多成绩。:

  1. 比方当在协程外面召集栈超越2M时,这是需求处置的成绩。,流畅行为准则还没有履行。,顺序一定挂,控制写坏堆,发生随机的、非回路的成绩。
  2. 显然,在应验中不思索多线索。,倘若在多线索事件中运转,需求使时间互相一致行为准则。。
  3. 现时的为了版本的协程有一个人商定,在协程里召集的作用不克不及闭塞在syscall,这显然是不科学的。。一个人整整的协程库,一定有非常非闭塞的经用希思凯尔的应验,说到底,仅一个人线索不克不及真正免于为了召集。。
  4. jmp_buf应验在形形色色的的平台上可能性不适合,终于,您需求在剩余部分平台上稍为重写行为准则。。

总结

自然应验协程剧照较比非常好转的的办法,像,倘若你可以应用glibc的ucontext库,可以应验B,而指责手工操作明智地使用作用召集的背景,多的风应验的协程库。

参考资料

  1. Coroutines in C。地址:~sgtatham/coroutines.html
  2. CERL++。地址:https://zhuanlan.zhihu.com/p/19945225?refer=impress-your-cat
  3. C 的 coroutine 库。地址:

下一篇:下一篇:没有了