|核心機(jī)制
狀態(tài)機(jī)是非常常用的框架之一,本質(zhì)就是通過記錄狀態(tài)值來執(zhí)行對(duì)應(yīng)動(dòng)作,但是有個(gè)問題就是每個(gè)對(duì)應(yīng)的狀態(tài)值都有對(duì)應(yīng)的動(dòng)作,如果碰到需要等待信號(hào)量再觸發(fā)的情況下需要特定處理,有沒更好的方法處理這種情況呢,答案很多是有的。要解決這需求就要保證代碼退出時(shí)和下次進(jìn)入時(shí)的位置是不變的,怎么實(shí)現(xiàn)呢?
實(shí)現(xiàn)這個(gè)需求的方式有很多,這里就使用純C來實(shí)現(xiàn):
#includeintfunction(void) { staticintstate; switch(state) { case0: do { printf("state:%d ",state); state=1; return0; case1:; printf("state:%d ",state); }while(0); } } intmain() { function();//輸出state:0 function();//輸出state:1 function();//輸出state:1 while(1) { } }
這里還是采用狀態(tài)機(jī)來實(shí)現(xiàn),由于狀態(tài)值沒有發(fā)生改變,函數(shù)調(diào)用時(shí)觸發(fā)的動(dòng)作不變,這就保證了函數(shù)退出時(shí)和再次進(jìn)入的“入口”相同。
|優(yōu)化代碼
在介紹優(yōu)化前,先介紹一下C相關(guān)的宏:
intmain() { printf("%d ",__LINE__);//顯示所在行號(hào) printf("%s ",__func__);//顯示所在函數(shù) printf("%s ",__TIME__);//顯示當(dāng)前時(shí)間 printf("%s ",__DATE__);//顯示當(dāng)前日期 printf("%s ",__FILE__);//顯示所處文件名,在源代碼中插入當(dāng)前源代碼文件名 printf("%d ",__STDC__);//編譯器遵循ANSI C標(biāo)準(zhǔn)時(shí)該標(biāo)識(shí)被賦值為1; return0; }
簡(jiǎn)單優(yōu)化一下:
#includeintstate=0; voidfunction_init(void) { state=0; } intfunction_handle(intcondition) { switch(state) { case0: do { state=__LINE__; case__LINE__: if(!condition) return0; else return1; }while(0); } } intmain() { //等待 intcondition=1; function_init(); if(!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } //觸發(fā) 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 "); } //觸發(fā) condition=0; function_init(); if(!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } while(1) { } }
簡(jiǎn)單封裝一下:
#include#defineBegin() switch(state) { case0: #defineWAIT(condition) do { state=__LINE__; case__LINE__: if(!condition) return0; else return1; }while(0) #defineEnd()} intstate=0; voidfunction_init(void) { state=0; } intfunction_handle(intcondition) { Begin(); WAIT(condition); End(); } intmain() { //等待 intcondition=1; function_init(); if(!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } //觸發(fā) 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 "); } //觸發(fā) condition=0; function_init(); if(!function_handle(condition)) { printf("pass "); } else { printf("obsolete "); } while(1) { } }
| 最后優(yōu)化
源碼:
#include#include #include #include #definePT_BEGIN() switch(pt->state) { case0: #definePT_END() pt->state=0; return0; } #definePT_WAIT_UNTIL(condition) do { pt->state=__LINE__; case__LINE__: if(!(condition)) return0; }while(0) typedefstruct { uint8_tstate; }pt_t; voidpt_init(pt_t*pt) { pt->state=0; } boolpt_run(pt_t*pt) { returnpt->state!=0; } intthread_fun(pt_t*pt) { staticuint32_tcounter=0; PT_BEGIN(); while(1) { printf("counter=%lu ",counter++); PT_WAIT_UNTIL(counter%10==0); } PT_END(); } intmain() { pt_tpt_a; pt_tpt_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); } } return0; }
最后就完成了一個(gè)簡(jiǎn)單的線程,純C編寫非常方便移植和改寫!
審核編輯:劉清
-
封裝技術(shù)
+關(guān)注
關(guān)注
12文章
550瀏覽量
67996 -
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7606瀏覽量
137071 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
492瀏覽量
27561
原文標(biāo)題:C語(yǔ)言|特殊狀態(tài)機(jī)
文章出處:【微信號(hào):玩轉(zhuǎn)單片機(jī),微信公眾號(hào):玩轉(zhuǎn)單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論