非常精简的开源 C 协程库:Protothreads

jopen 10年前

开源 C 协程库 protothreads。这是一个全部用 ANSI C 写成的库,之所以称为“蝇量级”的,就是说,实现已经不能再精简了,几乎就是原语级别。事实上 protothreads 整个库不需要链接加载,因为所有源码都是头文件,类似于 STL 这样不依赖任何第三方库,在任何平台上可移植;总共也就 5 个头文件,有效代码量不足 100 行;API 都是宏定义的,所以不存在调用开销;最后,每个协程的空间开销是 2 个字节(是的,你没有看错,就是一个 short 单位的“栈”!)当然这种精简是要以使用上的局限为代价的。

主要特性: 

  • 非常小的内存开销 - 每个原始线程只有两个字节,没有多余的堆栈
  • 高度便携 - Protothreads库是100%纯C开发
  • 可以在操作系统中使用或单独使用
  • 提供阻塞等待而不完整的多线程或堆栈切换
#include "pt.h"     struct pt pt;  struct timer timer;     PT_THREAD(example(struct pt *pt))  {    PT_BEGIN(pt);       while(1) {      if(initiate_io()) {        timer_start(&timer);        PT_WAIT_UNTIL(pt,           io_completed() ||           timer_expired(&timer));        read_data();      }    }    PT_END(pt);  }

协程(coroutine)顾名思义就是“协作的例程”(co-operative routines)。跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程技巧。实际上协程的概念比线程还要早,按照 Knuth 的说法“子例程是协程的特例”,一个子例程就是一次子函数调用,那么实际上协程就是类函数一样的程序组件,你可以在一个线程里面轻松创建数十万个协程,就像数十万次函数调用一样。只不过子例程只有一个调用入口起始点,返回之后就结束了,而协程入口既可以是起始点,又可以从上一个返回点继续执行,也就是说协程之间可以通过 yield 方式转移执行权,对称(symmetric)、平级地调用对方,而不是像例程那样上下级调用关系。当然 Knuth 的“特例”指的是协程也可以模拟例程那样实现上下级调用关系,这就叫非对称协程(asymmetric coroutines)。


详见:http://coolshell.cn/articles/10975.html