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

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

1.如何理解协程(coroutine)

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

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

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

def generate_int():
	i = 0
	while 1:
		yield i
		i += 1

下面是运行结果:

>> x = generate_int()
>> x
<generator object f at 0x7fb914988e08> 
>> next(x)
0
>> next(x)
1
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 };
#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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值