執行緒池下的三種socket模型分析

2021-09-28 04:36:08 字數 1605 閱讀 9934

執行緒池:預先建立指定數量的執行緒,節省在實際應用中不斷新建和**子執行緒的時間。

每個執行緒都阻塞於accept上,當有客戶端連線時,阻塞accept上的執行緒都被喚醒,競爭,只有乙個執行緒去處理accept,其他執行緒繼續阻塞。

設定乙個主控執行緒,主控執行緒accept,其他任務執行緒等待主控執行緒分配任務

引入互斥鎖,每個執行緒先爭一把鎖,誰搶到這把鎖mutex,誰去accept,連線後馬上釋放鎖,啟動多乙個執行緒,避免a執行緒accept後又有乙個客戶端馬上連線。

注意:並不是每一次釋放鎖後,其他執行緒又要重新去競爭。實質上,核心實現搶鎖的機制:第一次屬於競態,而後面未競爭到的執行緒都阻塞在pthread_mutex_lock上,並且排好隊,每次釋放鎖後將會先優先執行隊首的第乙個執行緒。

pthread_mutex_lock(&mutex);

accept(listenfd,&client_addr,&client_addrlen);

pthread_mutex_unlock(&mutex);

...處理客戶端請求...

執行緒池大小在一開始已被預先固定下來,有可能會出現執行緒過剩執行緒緊缺的問題,導致應用中不靈活。

解決:

設定最大閥值max_work_num //最大執行緒的數量,避免無限制的建立執行緒導致效能下降。

設定最小閥值min_work_num //當服務量少時,提高效能

當前閥值cur_work_num //目前處於哪種狀態

正在使用的執行緒數量this_work_num //根據此來改變閥值

執行緒狀態status //busy or free

場景分析:

當引入以上5個變數後,執行緒池可根據當前客戶端連線的數量動態擴容或減少。(例如當前閥值為最大時,根據執行緒狀態獲取正在使用的執行緒數量,在根據數量來調整當前閥值該擴充還是減少,並且範圍在min_work_num至max_work_num之間。)

執行緒擴充操作:主控執行緒呼叫pthread_create建立。

執行緒減少操作:主控執行緒呼叫pthread_kill傳送訊號來終止指定執行緒。

難點注意:

對於pthread_kill的操作:這裡還需要作進一步講解,我們知道執行緒的結束有 子執行緒呼叫pthread_exit終止自己 以及 主控執行緒呼叫pthread_cancel傳送終止訊號給子執行緒,注意pthread_cancel後系統並不會馬上關閉被取消執行緒,只有在被取消執行緒下次系統呼叫時,才會真正結束執行緒,或呼叫pthread_testcancel,讓核心去檢測是否需要取消當前執行緒,但是如果要殺死的子執行緒阻塞在pthread_mutex_lock下,子執行緒將無法終止,同理也無法自身呼叫pthread_kill終止自己,因為已經阻塞。因此引入了pthread_kill操作,該操作無須像pthread_cancel需等待下一次系統呼叫才能完成,還需注意執行緒間不共享訊號遮蔽字,當執行緒處於空閒狀態時,通過指定sigusr訊號來設定捕捉函式,在訊號捕捉函式內呼叫pthread_exit終止自己,當執行緒處於繁忙時,設定訊號遮蔽字。

通過以上分析,基本上可以動手自行設計模型3,操作有些複雜,**部分本人後續補上,如果不足請指正,感謝!

三種執行緒池模型

half sync half async hs ha 將執行緒分為兩個部分,一部分專門處理非同步事件,另一部分專門處理同步事件。在網路伺服器裡,一般非同步事件指的是socket事件,同步事件指的是業務邏輯。leader follower lf 所有執行緒輪流監聽請求,監聽到後將監聽令牌傳到下乙個執行...

三種執行緒池比較

伺服器程式 最核心的任務之一就是處理一組任務,在處理一組任務的時候最常見的做法是用執行緒池,最常見的執行緒池一般是由一組執行緒等待在乙個訊號燈上,有乙個任務到達後解鎖乙個執行緒,讓該執行緒去處理任務,執行緒處理完成後又回歸到執行緒池,此做法比來乙個任務分配乙個執行緒的古老方法效率高了很多,但這也不是...

三種執行緒池比較

三種執行緒池比較 伺服器程式最核心的任務之一就是處理一組任務,在處理一組任務的時候最常見的做法是用執行緒池,最常見的執行緒池一般是由一組執行緒等待在乙個訊號燈上,有乙個任務到達後解鎖乙個執行緒,讓該執行緒去處理任務,執行緒處理完成後又回歸到執行緒池,此做法比來乙個任務分配乙個執行緒的古老方法效率高了...