• 2009-05-09

    发现一个不错的东西:protothreads - [源码分析]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://redboot.blogbus.com/logs/39116533.html

    最近在porting uIP,就顺便读了下uIP的代码。

    意外发现一个比较好玩的东西 Protothreads

    这是个什么东西呢?

    文档上说,这是一个极轻量级的无栈线程库。

    简单的说,就是在一个死循环 while(1){} 里面跑多个线程,但是,又不必为每个线程都分配一个栈。

    因为为每个线程都分配一个栈空间还要分配一个数据结构,太耗费内存了。

    所以,它特别适合在内存受限的嵌入式系统里面用。

    比如,一个小嵌入式系统,要支持网络协议,还要支持客户的命令,而根本就没有一个操作系统。

    你就可以用 Protothreads 来做一个简单的线程调度。

    就好像有了个小操作系统。而其代价又是如此之小。不单没有什么调度算法的cpu开销。

    内存方面为每个线程也只需要多花两个字节。

    还支持信号量操作,而且不用汇编,只用c语言和一些宏定义。

    哇,简直太幸福啦!

    这么酷的玩意是怎么搞的呢?

    其实,说起来也不麻烦,他提供了一些宏,我读了一些,展开来大致就相当于下面这种形式:

    while(1){

    switch(s) {

    case 0:...

    case x:...

    case y: ...

    }

    }

    从下面几个宏的定义就能看出来了:

    #define     LC_INIT(s)   s = 0;
    #define     LC_RESUME(s)   switch(s) { case 0:
    #define     LC_SET(s)   s = __LINE__; case __LINE__:
    #define     LC_END(s)   }   

     

    不过,这样做显然也是有一些代价的,

    第一,使用局部变量要极为小心,(文档建议不要用)

    很简单,没有栈啊,局部变量放哪里(这个解释不严密,具体看看实现就清楚了)?

    第二,当调用函数时,没多调用一层就要多加一个变量,记录执行到这个函数的位置。

    以便下次进入时,能找到合适的位置。

     

    不过,不管怎么讲,这还是很好玩的一个“线程”库,如果手上碰巧碰到一个内存极少的硬件可以用下。

     


    收藏到:Del.icio.us