C语言实现协程(coroutine)

Donald Knuth 说过:

“子程序就是协程的一种特例。”

编程过程中,最常用的就是函数调用,这时对于调用方来说,被调函数就是子程序(subroutine)。可以把协程理解相互配合工作的函数,函数之间可以相互切换,并且能够从上次切换的状态重新开始执行。
python 程序中的 yield 关键字可以将一个函数停止执行并保持执行状态,等待再次被调用。

   
def rangeN(a, b): 
    i = a 
    while (i < b): 
        yield i 
        i += 1    
  
for i in rangeN(1, 5): 
        print(i) 

如果把协程理解成相互配合工作的函数,那么如何理解“子程序就是协程的一种特例。”这句话呢?
在经典的c程序中,函数的调用是基于栈进行的,函数调用结束后所有信息出栈,被调函数结束执行,状态丢失。c语言没有yield这样的关键字,那么如何做到一个函数的来回切换呢?

  1. 使用静态变量记录函数执行状态。
  2. 使用goto关键字跳转到必要的执行点。
int rangeV2(int a, int b) {
        static long long int i;
        static int state = 0;
        switch (state) {
                case 0:
                        state = 1;
                        i = a;
                        while (i < b) {
                                return i;

L:i++;
                        }
                        state = 0;
                        return 0;
                case 1:
                        goto L;
        }
}


int main() {
        int i;
        //for (; i = range(1, 5);) {
        //      printf("debug>>>>>%d\n", i);
        //}
        //
        i = rangeV2(1, 5);
        while (i != 0) {
                printf("debug>>>>%d\n", i);

                i = rangeV2(1, 5);
        }
}

如果不想使用goto关键字,可以使用 duff’s device (什么是达夫设备,参考这篇文章) 来实现:


int range(int a, int b) {
        static long long int i;
        static int state = 0;
        switch (state) {
                case 0:
                        state = 1;
                        //for (i = a; i < b; i++) {
                        //      return i;
                        //      case 1:;
                        //}

                        i = a;
                        while (i < b) {
                                return i;

                                case 1:
                                i++;
                        }
        }
        state = 0;
        return 0;
}

你可能感兴趣的:(C)