本文涉及到的Protothread機制知識,在http://www.cnblogs.com/songdechiu/p/5793717.htmlhtml
進程類型主要有協同式(cooperative)和搶佔式(preemptive)兩種。git
協同式進程,要等其餘進程運行完進程實體函數(進程不必定運行完,這個時候有多是阻塞,總之只要執行到return語句,具體看protothread機制),而後才能開始運行。github
搶佔式進程,會優先運行,當有搶佔式進程須要執行時,協同式進程將會被掛起,直到搶佔式進程實體函數執行完畢。中斷和實時任務就須要用搶佔式進程實現。函數
struct process { struct process *next;//指向下個進程結構體,在進程鏈表中使用 #if PROCESS_CONF_NO_PROCESS_NAMES//配置進程字符串名字? #define PROCESS_NAME_STRING(process) ""//沒有,空 #else //有字符串名字 const char *name;//定義進程字符串名字 #define PROCESS_NAME_STRING(process) (process)->name//取名字 #endif PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t));//進程執行實體函數 struct pt pt;//pt結構體,存儲實體函數阻塞時的位置 unsigned char state, needspoll;//state是進程狀態,needspoll標誌進程是否須要優先執行 };
process_list ----->oop
參考:http://blog.chinaunix.net/uid-9112803-id-2976187.htmlui
只要抓住了進程鏈表頭process_list,那麼進程的各類操做都作獲得了。spa
HelloWorld例子.net
PROCESS_THREAD(hello_world_process, ev, data) { PROCESS_BEGIN(); printf("Hello, world\n"); PROCESS_END(); } #define PROCESS_THREAD(name, ev, data) \ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_event_t ev, \ process_data_t data)) #define PT_THREAD(name_args) char name_args
最後展開爲unix
static char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data) { //略 }
這就是進程的執行實體函數code
非同步事件處理中,先將事件放到事件隊列中,而後事件處理程序再把事件傳遞給接收這個事件的進程。
同步事件處理中,事件立馬就傳遞給了特定的進程,表現爲立馬執行ProcessB的執行實體函數。
推舉某個進程,讓這個進程儘量快的執行。搶佔式進程的惟一調用方式。
先處理全部poll的進程,再處理一個事件,最後返回剩餘的事件數。
int process_run(void) { /* Process poll events. */ if(poll_requested) { do_poll(); } /* Process one event from the queue */ do_event(); return nevents + poll_requested; }
https://github.com/contiki-os/contiki/wiki/Processes
http://blog.chinaunix.net/uid-9112803-id-2976187.html
源碼:$contiki$\core\sys\process.c
源碼:$contiki$\core\sys\process.h