pt-thread使用与介绍
1. 简介
pt-thread
是一种专为内存容量严重受限的系统设计的无堆栈线程,可用于深度嵌入式系统或传感器网络节点。它用C语言实现,为事件驱动型系统提供了线性代码执行方法。可被用于带RTOS或不带RTOS的系统中。
它非常轻量,没有每个线程堆栈的开销。其设计目的是无需复杂状态机或完全多线程即可实现顺序控制流。提供条件阻塞接口。
2. 主要特征
- 无需特定的机器汇编代码,其原型库是纯C的
- 不使用易出错的函数如
longjmp()
- 非常小的内存开销,每个线程只需2字节
- 可以与带OS或不带OS一起使用
- 提供阻塞等待而不需要完全多线程或堆栈切换
3. 参考应用
- 内存受限制的系统
- 事件驱动的协议栈
- 深度嵌入式系统
- 传感器网络节点
pt-thread
库是基于BSD协议协议发布的,允许非商业或商业用途。
4. 如何使用
4.1 移植方法
在工程中移植使用pt-thread
非常简单,只需加入3个头文件即可,分别是pt.h
、lc.h
和lc-switch.h
,所有使用pt-thread
的位置#include "pt.h"
即可。当然它也提供了简单信号量方法,只需加入pt-sem.h
头文件。
4.2 局部变量!!!
由于pt-thread
阻塞调用时不会保存堆栈上下文,因此线程阻塞时局部变量不会保留。这意味着应当最大程度的限制局部变量在线程内的使用。切记!
4.3 调度
其线程是通过对其原型函数的重复调用驱动的。每次函数被调用,线程将运行知道阻塞或退出。因此,不管线程内部有无条件阻塞,都要加入主动阻塞PT_YIELD
,以释放CPU占用。
4.4 实现
其线程实现方式有两种:
- 基于C
switch()
语句实现(#include "lc-switch.h"
):
typedef unsigned short lc_t;
#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) }
- 基于
goto lable
语句实现 (#include "lc-addrlabels.h"
):
typedef void * lc_t;
#define LC_INIT(s) s = NULL
#define LC_RESUME(s) \
do { \
if(s != NULL) { \
goto *s; \
} \
} while(0)
#define LC_CONCAT2(s1, s2) s1##s2
#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
#define LC_SET(s) \
do { \
LC_CONCAT(LC_LABEL, __LINE__): \
(s) = &&LC_CONCAT(LC_LABEL, __LINE__); \
} while(0)
#define LC_END(s)