一个“蝇量级”C语言协程库
15页1、一个轻量级的协助程框架协程(coroutine)顾名思义就是“协作的例程”(co-operative routines)。跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程技巧。实际上协程的概念比线程还要早,按照 Knuth 的说法“子例程是协程的特例”,一个子例程就是一次子函数调用,那么实际上协程就是类函数一样的程序组件,你可以在一个线程里面轻松创建数十万个协程,就像数十万次函数调用一样。只不过子例程只有一个调用入口起始点,返回之后就结束了,而协程入口既可以是起始点,又可以从上一个返回点继续执行,也就是说协程之间可以通过 yield 方式转移执行权,对称(symmetric)、平级地调用对方,而不是像例程那样上下级调用关系。当然 Knuth 的“特例”指的是协程也可以模拟例程那样实现上下级调用关系,这就叫非对称协程(asymmetric coroutines)。基于事件驱动模型我们举一个例子来看看一种对称协程调用场景,大家最熟悉的“生产者-消费者”事件驱动模型,一个协程负责生产产品并将它们加入队列,另一个负责从队列中取出产品并使用它。
2、为了提高效率,你想一次增加或删除多个产品。伪代码可以是这样的:12345678910111213# producer coroutineloopwhile queue is not fullcreate some new itemsadd the items to queueyield to consumer# consumer coroutineloopwhile queue is not emptyremove some items from queueuse the itemsyield to producer大多数教材上拿这种模型作为多线程的例子,实际上多线程在此的应用还是显得有点“重量级”,由于缺乏 yield 语义,线程之间不得不使用同步机制来避免产生全局资源的竟态,这就不可避免产生了休眠、调度、切换上下文一类的系统开销,而且线程调度还会产生时序上的不确定性。而对于协程来说,“挂起”的概念只不过是转让代码执行权并调用另外的协程,待到转让的协程告一段落后重新得到调用并从挂起点“唤醒”,这种协程间的调用是逻辑上可控的,时序上确定的,可谓一切尽在掌握中。当今一些具备协程语义的语言
3、,比较重量级的如C#、erlang、golang,以及轻量级的python、lua、javascript、ruby,还有函数式的scala、scheme等。相比之下,作为原生态语言的 C 反而处于尴尬的地位,原因在于 C 依赖于一种叫做栈帧的例程调用,例程内部的状态量和返回值都保留在堆栈上,这意味着生产者和消费者相互之间无法实现平级调用,当然你可以改写成把生产者作为主例程然后将产品作为传递参数调用消费者例程,这样的代码写起来费力不讨好而且看起来会很难受,特别当协程数目达到十万数量级,这种写法就过于僵化了。这就引出了协程的概念,如果将每个协程的上下文(比如程序计数器)保存在其它地方而不是堆栈上,协程之间相互调用时,被调用的协程只要从堆栈以外的地方恢复上次出让点之前的上下文即可,这有点类似于 CPU 的上下文切换,遗憾的是似乎只有更底层的汇编语言才能做到这一点。难道 C 语言只能用多线程吗?幸运的是,C 标准库给我们提供了两种协程调度原语:一种是setjmp/longjmp,另一种是ucontext 组件,它们内部(当然是用汇编语言)实现了协程的上下文切换,相较之下前者在应用上会产生相当的
4、不确定性(比如不好封装,具体说明参考联机文档),所以后者应用更广泛一些,网上绝大多数 C 协程库也是基于 ucontext 组件实现的。“蝇量级”的协程库在此,我来介绍一种“蝇量级”的开源 C 协程库protothreads。这是一个全部用 ANSI C 写成的库,之所以称为“蝇量级”的,就是说,实现已经不能再精简了,几乎就是原语级别。事实上 protothreads 整个库不需要链接加载,因为所有源码都是头文件,类似于 STL 这样不依赖任何第三方库,在任何平台上可移植;总共也就 5 个头文件,有效代码量不足 100 行;API 都是宏定义的,所以不存在调用开销;最后,每个协程的空间开销是 2 个字节(是的,你没有看错,就是一个 short 单位的“栈”!)当然这种精简是要以使用上的局限为代价的,接下来的分析会说明这一点。先来看看 protothreads 作者,Adam Dunkels,一位来自瑞典皇家理工学院的计算机天才帅哥。话说这哥们挺有意思的,写了好多轻量级的作品,都是 BSD 许可证。顺便说一句,轻量级开源软件全世界多如牛毛,可像这位哥们写得如此出名的并不多。比如嵌入式网络
《一个“蝇量级”C语言协程库》由会员工****分享,可在线阅读,更多相关《一个“蝇量级”C语言协程库》请在金锄头文库上搜索。
《去打开大自然绿色的课本》教学实录
微波通信原理的详细介绍
2018-2019年高考英语学业水平测试一轮复习 书面表达 话题17 语言学习
企业战略管理解决方案及案例分析
液压支架检修技术规范
2022年贵州省安全员B证资格证书资格考核试题附参考答案90
四年级下册第117~118页 数学广角
作业条件危险性评价法(LECD)
加工生产胶合板的工艺流程
四川农业大学21秋《动物遗传应用技术专科》复习考核试题库答案参考套卷13
工程专业实习报告模板汇编8篇
小学组奥运知识答题
母亲节的资料
小班本学期教学计划
公司转正的申请书怎么写
[工作计划]中心学校教研工作计划1
防爆电气设备的修理
入户门施工方案
团支书学期工作总结三篇 团支书新学期工作计划
爱护环境珍惜资源的建议书
2023-06-17 13页
2024-01-28 9页
2023-08-09 6页
2022-10-21 7页
2023-09-06 4页
2023-04-28 7页
2022-09-12 7页
2024-02-20 19页
2022-11-24 9页
2023-11-28 9页