protothread学习

     ◆ protothread是专为资源有限的系统设计的一种耗费资源特别少并且不使用堆栈的线程模型,相比于嵌入式操作系统,其有如下优点:

      1. 以纯C语言实现,无硬件依靠性; 因此不存在移植的困难。

      2. 极少的资源需求,每个Protothread仅需要2个额外的字节;

      3. 支持阻塞操纵且没有栈的切换。

      ◆它的缺陷在于:

      1. 函数中不具备可重入型,不能使用局部变量;

      2. 按顺序判断各任务条件是否满足,因此无优先级抢占;

      3. 任务中的各条件也是按顺序判断的,因此要求任务中的条件必须是依次出现的。

      ◆ protothread的阻塞机制: 在每个条件判断前,先将当前地址保存到某个变量中,再判断条件是否成立,若条件成立,则往下

          运行;若条件不成立,则返回。

      ◆ protothread基本源码及注释:

         #ifndef PC_H #define PC_H typedef unsigned int INT16U; struct pt { INT16U lc; }; #define PT_THREAD_WAITING 0 #define PT_THREAD_EXITED 1 //初始化任务变量,只在初始化函数中执行一次就行 #define PT_INIT(pt) (pt)->lc = 0 //启动任务处理,放在函数开始处 #define PT_BEGIN(pt) switch((pt)->lc) { case 0: // 等待某个条件成立,若条件不成立则直接退出本函数,下一次进入本函数就直接跳到这个地方判断 // __LINE__ 编译器内置宏,代表当前行号,比如:若当前行号为8,则 s = __LINE__; case __LINE__: 展开为 s = 8; case 8: #define PT_WAIT_UNTIL(pt,condition) (pt)->lc = __LINE__; case __LINE__: / if(!(condition)) return // 结束任务,放在函数的最后 #define PT_END(pt) } // 等待某个条件不成立 #define PT_WAIT_WHILE(pt,cond) PT_WAIT_UNTIL((pt),!(cond)) // 等待某个子任务执行完成 #define PT_WAIT_THREAD(pt,thread) PT_WAIT_UNTIL((pt),(thread)) // 新建一个子任务,并等待其执行完退出 #define PT_SPAWN(pt,thread) / PT_INIT((pt)); / PT_WAIT_THREAD((pt),(thread)) // 重新启动某任务执行 #define PT_RESTART(pt) PT_INIT(pt); return // 任务后面的部分不执行,直接退出 #define PT_EXIT(pt) (pt)->lc = PT_THREAD_EXITED;return #endif

     

       ◆ 实例及展开源码:

         应用实例:

          static struct pt pt1,pt2; static int protothread1_flag,protothread2_flag; // ======================================== // 线程1 // ======================================== static void protothread1(struct pt *pt) { PT_BEGIN(pt); // 开始时调用 while(1) { // 应用代码 protothread1_flag = 1; PT_WAIT_UNTIL(pt,protothread2_flag != 0); // 等待protothread2_flag 标志置位 protothread2_flag = 0; } PT_END(pt); // 结束时调用 } // ======================================== // 线程2 // ======================================== static void protothread2(struct pt *pt) { PT_BEGIN(pt); while(1) { // 应用代码 protothread2_flag = 1; PT_WAIT_UNTIL(pt,protothread1_flag != 0); // 等待protothread1_flag 标志置位 protothread1_flag = 0; } PT_END(pt); } // ======================================== // 主函数 // ======================================== void main(void) { PT_INIT(&pt1); // 初始化 PT_INIT(&pt2); while(1) { protothread1(&pt1); protothread2(&pt2); } }

        线程1,2的展开式:

          // ======================================== // 线程1 // ======================================== static void protothread1(struct pt *pt) { // PT_BEGIN(pt);展开 switch(pt->lc) { case 0: ; while(1) { protothread1_flag = 1; // PT_WAIT_UNTIL(pt,protothread2_flag != 0);展开 // 条件判断部分,条件不成立,则调度 pt->lc = 26; // 假定当前为26行 case 26: if(protothread2_flag == 0) return; // 若protothread2_flag未发生,返回 protothread2_flag = 0; } // PT_END(pt); 对应switch } } // ======================================== // 线程2 // ======================================== static void protothread2(struct pt *pt) { switch(pt->lc) { case 0: ; while(1) { protothread2_flag = 1; pt->lc = 44; case 44: if(protothread1_flag == 0) return; myFunc2(); protothread1_flag = 0; } } }

 

你可能感兴趣的:(thread,struct,语言,任务,编译器,嵌入式操作系统)