接上文:線程池的設計(一):半同步半異步線程池的設計
git
領導者追隨者模式在使用方式上與半同步半異步模式相同,如下主要介紹不一樣的實現部分,相同部分一筆帶過。github
本文講述的只是領導者追隨者線程池的一種實現,不得不說,這種模式真的很複雜。 異步
兩種模式的主要區別在於任務隊列的實現。函數
領導者追隨者線程池的工做流程:性能
代碼實現:https://github.com/421986908/Leader_Followersspa
1.啓動:.net
a.生成一組線程,放入線程數據;線程
2.添加任務:設計
a.任務隊列的實現是一個單向鏈表,添加任務就是向鏈表的表尾添加一個元素;指針
任務隊列的實現:
①. 每個任務的具體定義應包含如下結構:線程函數名、線程函數傳入的參數和指向下一個任務的指針。結構體定義以下:
struct job { void* (*callback_function)(void *arg); void *arg; struct job *next; };
②. 新增任務時,一樣要先判斷queue_cur_num
是否大於max_queue_num,判斷線程池和隊列是否處於服務的狀態。添加任務只要將任務添加到鏈表的表尾便可,核心代碼片斷以下:
pjob->callback_function = callback_function; pjob->arg = arg; pjob->next = NULL; if(pool->head == NULL) { pool->head = pool->tail = pjob; } else { pool->tail->next = pjob; pool->tail = pjob; }
工做者線程在結束任務後,會繼續進入wait狀態,至關於從新進入排隊。此例中的任務隊列能夠類比於機場打車時的乘客隊列,而工做者線程就至關於出租車。
③. 工做者線程wait到新任務時,會首先進行任務隊列的操做,即轉換領導者的身份,選出單鏈表表頭的下一位爲領導者,同時要注意維護隊列的長度queue_cur_num
,核心代碼片斷以下:
pool->queue_cur_num--; pjob = pool->head; if(pool->queue_cur_num == 0) { pool->head = pool->tail = NULL; } else { pool->head = pjob->next; }
3.中止:等待全部線程結束後中止線程池。
關於領導者追隨者線程池問答:
1.相比半同步半異步線程池,領導者追隨者的優點在哪裏? 不用進行線程間的上下文切換,性能獲得提升。
T(L/F)=T(多路分離)+T(分配)+T(處理)+T(同步)+T(上下文)
T(H/H)=T(多路分離)+T(分配)+T(處理)+T(同步)+T(數據傳遞)+T(上下文)
參照文檔:
《領導者/追隨者》http://blog.csdn.net/hzhsan/article/details/25018167