C语言标准库在电脑哪里,C语言标准库之setjmp -电脑资料

协程的介绍

协程(coroutine),意思就是“协作的例程”(co-operative routines),最早由Melvin Conway在1963年提出并实现,

实际上协程的概念比线程还要早,按照 Knuth 的说法“子例程是协程的特例”,一个子例程就是一次子函数调用,那么实际上协程就是类函数一样的程序组件,你可以在一个线程里面轻松创建数十万个协程,就像数十万次函数调用一样。只不过子例程只有一个调用入口起始点,返回之后就结束了,而协程入口既可以是起始点,又可以从上一个返回点继续执行,也就是说协程之间可以通过 yield 方式转移执行权,对称(symmetric)、平级地调用对方,而不是像例程那样上下级调用关系。当然 Knuth 的“特例”指的是协程也可以模拟例程那样实现上下级调用关系,这就叫非对称协程(asymmetric coroutines)。

setjmp.h

setjmp/longjmp 其实是C语言标准库中的内容,它被定义在头文件中,我认识的相当部分的人包括写过很多年C/C++的都表示没听过,并且他们在了解了一些setjmp的特性和功能之后还不以为然,说我又不会用到它;然而你们想过为什么标准库中会去实现一个相对这么怪异特性的语法支持?原因很简单,就是为了实现协程(coroutine),如果你一开始就给自己定位成协程的使用者,不关心它具体怎么实现的,甚至给自己定位成从不用协程,后面的内容你放心可以直接略过。

我们首先来看 setjmp/longjmp 这两个函数的定义。

int setjmp( jmp_buf _Buf );

void longjmp( jmp_buf _Buf, int _Value);

使用注意事项:

1、setjmp与longjmp结合使用时,它们必须有严格的先后执行顺序,也即先调用setjmp函数,之后再调用longjmp函数,以恢复到先前被保存的“程序执行点”。否则,如果在setjmp调用之前,执行longjmp函数,将导致程序的执行流变的不可预测,很容易导致程序崩溃而退出

2、longjmp必须在setjmp调用之后,而且longjmp必须在setjmp的作用域之内。具体来说,在一个函数中使用setjmp来初始化一个全局标号,然后只要该函数未曾返回,那么在其它任何地方都可以通过longjmp调用来跳转到 setjmp的下一条语句执行。实际上setjmp函数将发生调用处的局部环境保存在了一个jmp_buf的结构当中,只要主调函数中对应的内存未曾释放 (函数返回时局部内存就失效了),那么在调用longjmp的时候就可以根据已保存的jmp_buf参数恢复到setjmp的地方执行,C语言标准库之setjmp》(https://www.unjs.com)。

说白一点就是:在使用 setjmp 时,最常见的一个错误用法就是对它做封装,不应该封装在一个函数中。比如:

复制代码

int try(breakpoint bp)

{

return setjmp(bp->jb);

}

void throw(breakpoint bp)

{

longjmp(bp->jb,1);

}

复制代码

这样写并不会引起编译错误,但是极易容易发生运行时错误,因为setjmp的栈是在try函数中,而下一次调用longjmp的时候try函数可能已经不在栈中被清除了。

来个简单的例子:

复制代码

#include

#include

jmp_buf buf;

void second()

{

printf("second\n");

longjmp(buf, 1);

}

void first()

{

second();

printf("first\n");

}

int coro_main()

{

if ( !(setjmp(buf)) )

{

first();

}

else

{

printf("main\n");

}

return 0;

}

复制代码

输出结果:

second

main

除此之外还有广为使用的C语言协程非标准库有 ucontext,据我所知ucontext应用更广泛一些,网上绝大多数 C 协程库也是基于 ucontext 组件实现的。有空下次再去研究研究它。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值