| 核心机制
状态机是非常常用的框架之一,本质就是通过记录状态值来执行对应动作,但是有个问题就是每个对应的状态值都有对应的动作,如果碰到需要等待信号量再触发的情况下需要特定处理,有没更好的方法处理这种情况呢,答案很多是有的。要解决这需求就要保证代码退出时和下次进入时的位置是不变的,怎么实现呢?
实现这个需求的方式有很多,这里就使用纯C来实现:
#includeint function(void) { static int state; switch (state) { case 0: do { printf("state:%d ", state); state = 1; return 0; case 1:; printf("state:%d ", state); } while (0); } } int main() { function(); // 输出state:0 function(); // 输出state:1 function(); // 输出state:1 while (1) { } }
这里还是采用状态机来实现,由于状态值没有发生改变,函数调用时触发的动作不变,这就保证了函数退出时和再次进入的“入口”相同。
| 优化代码
在介绍优化前,先介绍一下C相关的宏:
int main() { printf("%d ",__LINE__);//显示所在行号 printf("%s ",__func__);//显示所在函数 printf("%s ",__TIME__);//显示当前时间 printf("%s ",__DATE__);//显示当前日期 printf("%s ",__FILE__);//显示所处文件名,在源代码中插入当前源代码文件名 printf("%d ",__STDC__);//编译器遵循ANSI C标准时该标识被赋值为1; return 0; }
简单优化一下:
#includeint state = 0; void function_init(void) { state = 0; } int function_handle(int condition) { switch (state) { case 0: do { state = __LINE__; case __LINE__: if (!condition) return 0; else return 1; } while (0); } } int main() { // 等待 int condition = 1; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } // 触发 condition = 0; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } // 等待 condition = 1; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } // 触发 condition = 0; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } while (1) { } }
简单封装一下:
#include#define Begin() switch (state) { case 0: #define WAIT(condition) do { state = __LINE__; case __LINE__: if (!condition) return 0; else return 1; } while (0) #define End() } int state = 0; void function_init(void) { state = 0; } int function_handle(int condition) { Begin(); WAIT(condition); End(); } int main() { // 等待 int condition = 1; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } // 触发 condition = 0; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } // 等待 condition = 1; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } // 触发 condition = 0; function_init(); if (!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } while (1) { } }
| 最后优化
源码:
#include#include #include #include #define PT_BEGIN() switch (pt->state) { case 0: #define PT_END() pt->state = 0; return 0; } #define PT_WAIT_UNTIL(condition) do { pt->state = __LINE__; case __LINE__: if (!(condition)) return 0; } while (0) typedef struct { uint8_t state; } pt_t; void pt_init(pt_t *pt) { pt->state = 0; } bool pt_run(pt_t *pt) { return pt->state != 0; } int thread_fun(pt_t *pt) { static uint32_t counter = 0; PT_BEGIN(); while (1) { printf("counter = %lu ", counter++); PT_WAIT_UNTIL(counter % 10 == 0); } PT_END(); } int main() { pt_t pt_a; pt_t pt_b; pt_init(&pt_a); pt_init(&pt_b); while (true) { if (!pt_run(&pt_a)) { thread_fun(&pt_a); } if (!pt_run(&pt_b)) { thread_fun(&pt_b); } } return 0; }
最后就完成了一个简单的线程,纯C编写非常方便移植和改写!
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !