当前位置:   article > 正文

linux下纯C实现协程(借助setjmp/longjmp) (未完成)_linux setjmp实现协程

linux setjmp实现协程

linux下纯C实现协程(借助setjmp/longjmp)

1.如何理解协程(coroutine)

首先,协程是在单个线程下讨论的概念;
何谓协程,就是满足如下定义:

  • 可以随时“挂起”
  • 之后可以回到“挂起”的状态继续执行

Python中的yield产生器很好地解释了协程的原理,它可以产生所有自然数;
重要的是,它不必每次从头开始生成,利用next()可以记住上次生成到了哪个数,它是有“记忆的”

def generate_int():
	i = 0
	while 1:
		yield i
		i += 1
  • 1
  • 2
  • 3
  • 4
  • 5

下面是运行结果:

>> x = generate_int()
>> x
<generator object f at 0x7fb914988e08> 
>> next(x)
0
>> next(x)
1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
2. 如何实现协程

因为函数调用会临时维护一个函数桢栈,一旦调用完毕,这个桢栈都会被摧毁; 所以关键在于,在函数的一次调用完毕时,记录下当时的"函数上下文"。

2.0 为何不适用GOTO
GOTO只能实现函数内的切换,而不能实现函数间的切换;

2.1 调用setjmp库
C中<setjmp.h>提供的setjmp和longjmp提供了这种方法;
int setjmp(jmp_buf env)
若直接调用则返回0,若从longjmp调用返回则返回非0值的longjmp中的val值
void longjmp(jmp_buf env, int val)
调用此函数则返回到最近的setjmp所在的地方,其中env就是setjmp中的 env,而val 则是使setjmp的返回值变为val。

2.2 实现一个简单协程
下面尝试实现这样一个功能:
在不修改某些变量的前提下,满足Condition执行完A后,仍然回来执行B;

if ( Condition )
	{ block A };
else
	{ block B };
  • 1
  • 2
  • 3
  • 4
#include <setjmp.h>
#include <stdio.h>
jmp_buf env;

void A(){
    printf("Now A\n");
    longjmp(env,1); //这里跳回到if中继续执行
}

void B(){
    printf("Now B\n");
}

int main()
{
    if (!setjmp(env)) //setjmp初次返回0,第二次回来返回的就是1
        A();
    else
        B();
    return 1;
}

>> 执行结果:
Now A
Now B
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/254736
推荐阅读
相关标签
  

闽ICP备14008679号