C/C++协程的实现方式总结

1、利用 C 语言的 setjmp 和 longjmp,函数中使用 static local 的变量来保存协程内部的数据。

函数原型:int setjmp(jmp_buf envbuf);

     void longjmp(jmp_buf envbuf, int val);

先调用setjmp,用变量envbuf记录当前的位置,然后调用longjmp,返回envbuf所记录的位置,并使setjmp的返回值为val。使用longjmp后,envbuf的内容会被销毁。

一个例子(引自《C专家编程》):

 1 #include <stdio.h> 
 2 #include <setjmp.h>
 3  
 4 jmp_buf buf; 
 5 
 6 banana()
 7 { 
 8     printf("in banana() 
"); 
 9     longjmp(buf,1); 
10     printf("you'll never see this,because i longjmp'd"); 
11 } 
12 
13 main() 
14 { 
15     if(setjmp(buf)) 
16         printf("back in main
"); 
17     else
18     { 
19         printf("first time through
"); 
20         banana(); 
21     } 
22 }

打印结果:

first time through

in banana()

back in main

 

2、利用C语言语法switch-case的技巧来实现(Protothreads) 。

设置一个标识符,改变标识符的值,通过switch-case对标识符值的判断操纵各协程函数轮流执行。

每个协程函数可配一个结构体,保存栈内容和状态机。

代码:https://github.com/georgeredinger/protothreads

3、使用汇编代码来切换上下文(实现c协程) 。

构建一个结构体保存栈内容和当前位置等上下文信息,利用汇编语言的跳转实现协程功能。

详情见:https://www.cnblogs.com/heluan/p/9899824.html

4、利用操作系统提供的接口:Linux的ucontext,Windows的Fiber。(云风的coroutine)

ucontext: makecontext()       创建上下文      

      getcontext()         读取上下文

      setcontext()         设置上下文

      swapcontext()        跳转上下文

Fiber(纤程):ConverThreadToFiber()     从当前线程进入纤程

      CreateFiber()         创建新纤程

      SwitchToFiber()        切换到纤程

      DeleteFiber()          删除纤程

                    如果删除当前纤程,会导致它所在的线程退出 

操作系统的接口函数本身,提供了保存栈内容的功能。

原文地址:https://www.cnblogs.com/heluan/p/9689751.html