quagga是開源路由器軟件,提供的用戶界面與思科,華為的路由器的人機接口幾乎一致,非常有學習價值,尤其是開源的協議代碼,簡直亮瞎了我的小眼睛。
quagga的介紹,我就不贅述了,有興趣的可以找度娘或者去官網看看。
一、通用庫thread
quagga是一個純C實現的項目。
C語言的項目,就是一個個C,H文件組成,當C文件很多的時候,相信一開始每個開源愛好者都會感到很頭疼吧,完全不知道這么多文件要怎么組織,怎么去閱讀吧?
哈,其實呢,quagga的C文件就像一個個散落在地上的珍珠,而thread這個庫就像織女手中的金絲線,把這些閃閃發光的珍珠完美的串連起來,就會發出璀璨奪目的光彩。
嗯,在quagga每個實現的協議的main函數里都會有如下類似的代碼:
1 /* Start finite state machine, here we go! */ 2 while (thread_fetch (bm->master, &thread)) 3 thread_call (&thread);
看到上面的注釋了嗎?嗯,沒錯,這是這個有限狀態機,但是程序猿們的直覺,過期的注釋都是不可靠,是的,這是個在有限狀態里,無限循環的狀態機。。
哦,要補充說明一下thread,這個不同於pthread,它的聲明如下:
1 /* Thread itself. */ 2 struct thread 3 { 4 thread_type type; /* thread type */ 5 thread_type add_type; /* thread type */ 6 struct thread *next; /* next pointer of the thread */ 7 struct thread *prev; /* previous pointer of the thread */ 8 struct thread_master *master; /* pointer to the struct thread_master. */ 9 int (*func) (struct thread *); /* event function */ 10 void *arg; /* event argument */ 11 union { 12 int val; /* second argument of the event. */ 13 int fd; /* file descriptor in case of read/write. */ 14 struct timeval sands; /* rest of time sands value. */ 15 } u; 16 int index; /* used for timers to store position in queue */ 17 struct timeval real; 18 struct cpu_thread_history *hist; /* cache pointer to cpu_history */ 19 const char *funcname; 20 const char *schedfrom; 21 int schedfrom_line; 22 };
它其實是描述了一個要在指定消息來臨時要執行的任務,並且提供了任務調度時需要判斷的時間片段。
下面就是一個協議代碼main函數中常見事件添加:
1 switch (event) 2 { 3 case ZCLIENT_SCHEDULE: 4 if (! zclient->t_connect) 5 zclient->t_connect = 6 thread_add_event (zclient->master, zclient_connect, zclient, 0); 7 break;
如此,thread_master就會源源不斷的搞出一些跟各個c文件都相關的事情來,然后通過thread_fetch的調度,然后thread_call中執行相應的任務。
1 (*thread->func)(thread);
執行完具體任務后,回到thread_fetch開始下一個thread。