C语言中的协程
来源:互联网 发布:mac同时登陆多个qq 编辑:程序博客网 时间:2024/06/03 17:05
引自:http://www.oschina.net/translate/coroutines-in-c
在《计算机程序设计艺术》中,Donald Knuth提供了一个解决这类问题的方法。他的方法是彻底丢掉堆栈的概念,不要再想一个进程作为调用者,另一个作为被调用者,把他们当做平等的协作者关系。
实际上就是:把传统的“调用”稍微改为一个不同的方式。新的“调用”将在某个地方保存返回值而不是堆栈上,并且还能跳转到另一个保存返回值的指定位置上。因此,解码器每次生成一个字符,就保存它的程序计数器并且跳转到上次解析器的位置-解析器每次都需要一个新的字符,它保存自己的程序计数器并且跳转到上次解码器的位置。程序可以在两个函数之间来回自如的传递需要的数据了。
理论上看起来很美,但实际中你却只能在汇编语言中使用,因为通用的高级语言没有一个支持调用原始的协程。像类似于C的都是依赖于基础的堆栈结构,因此当在函数间进行数据传递时,一个必须作为调用者,领一个必须作为被调用者。所以如果你想写可移植的代码,这种技术和Unix管道一样不切实际。
int fuction(void){ static int i, state=0; switch(state){ case 0: goto LABEL0; case 1: goto LABEL1; } LABEL0: for(i=0; i<10; i++) { state = 1; return i; LABEL1:; }}更进一步:
int function(void){ static int i, state=0; switch(state){ case 0: for(i=0; i<10; i++){ state = 1; retrn i; case 1:; } }}更进一步
#define crBegin static int state=0; switch(state){case 0:#define crReturn(i,x) do(state=i; return x; case i:;)while(0)#define crFinish }int function(void){ static int i; crBegin; for(i=0; i<10; i++) crReturn(1,i); crFinish;}
剩下的唯一问题是传给crReturn的第一个参数。就像在上一节引进一个新标签一样,我们必须避免与已存在的标签名冲突,确保所有给crReturn的状态参数都是不同的。这影响是相当小的 -- 编译器会抓住它并并不让它在运行时出错 -- 但我们还是要避免这样做。
虽然这可以解决,ANSI C还是提供了扩展到当前行号的专门的宏名:__LINE__,因此我们可以把crReturn重写成:
#define crReturn(x) do(state=__LINE__; return x;\case:__LINE__;)while(0)
0 0
- C语言中的协程
- C语言中的static
- C语言中的指针
- C语言中的sizeof
- C 语言中的随机数
- c语言中的指针
- c语言中的volatile
- c语言中的volatile
- C语言中的#与##
- C语言中的符号
- C语言中的移位
- c语言中的注释
- c 语言中的static
- C语言中的#号
- c语言中的fscanf
- C语言中的qsort
- C语言中的复数
- c语言中的点点滴滴
- 前端框架选择
- PsTools远程执行Windows命令
- 大范甘迪日天儿太热他
- js + php 读取、播放视频流 兼容firefox,chrome,ie,mac的safari,ios的safari,ios的微信浏览器(文件读取文件流篇)
- js编码问题
- C语言中的协程
- python 2.7 django1.6 ctype = ctype.encode(default_encoding) # omit in 3.x!
- java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFil
- 第7周作业2-极值计算--曾麒城
- ADN中国团队参加微软的Kinect全国大赛获三等奖,我们团队的创意项目用Kinect在Naviswork中虚拟漫游
- 个人封装的一个Camera类
- Java程序员十条戒规
- “据说女生筷子拿得多高,就说明将来会嫁得多远”
- No20_factorial_digit_num