完成埠之二 執行緒池部分

2022-05-08 14:27:12 字數 1845 閱讀 4405

一、執行緒池的基本原理

在傳統伺服器架構中, 常常是有乙個總的監聽執行緒監聽有沒有新的使用者連線伺服器, 每當有乙個新的使用者連線進入, 伺服器端就開啟乙個新的執行緒去處理這個使用者的請求,與其進行資料的收發。

這個執行緒只服務於這個使用者, 當使用者與伺服器端關閉連線以後, 伺服器端才銷毀這個執行緒。然而頻繁地開闢與銷毀執行緒極大地占用了系統的資源。而且在大量使用者的情況下, 少則1000,多則上萬,系統為了開闢和銷毀執行緒將浪費大量的時間和資源。

執行緒池技術很好的解決了這個問題,它的基本思想就是在程式開始時就在記憶體中開闢一些執行緒, 當有新的客戶請求到達時,

不是新建立乙個執行緒為其服務, 而是從「池子」中選擇乙個空閒的執行緒為新的客戶請求服務,服務完畢後,執行緒不是退出,而是進入空閒執行緒池中。

通過對多個任務重用已經存在的執行緒物件, 降低了對執行緒物件建立和銷毀的開銷。當客戶請求時, 執行緒物件已經存在, 可以提高請求的響應時間, 從而整體地提高了系統服務的表現。

二、執行緒池的實現

本示例中採用微軟自帶的執行緒池api

三、使用注意事項:

使用執行緒池用到的最重要的 windows api 函式:queueuserworkitem,其定義如下:

bool winapi queueuserworkitem(

__in lpthread_start_routine function,

__in pvoid context,

__in ulong flags

);● 引數 function 是乙個函式指標,指向執行緒池中的執行緒必須要完成的工作,該函式必須具有以下形式:

dword winapi function(lpvoid lpparam);

大家可以發現,這個函式跟建立執行緒的執行緒函式擁有相同的形式;

● 引數 context 是乙個 void 型別的指標,與傳遞給執行緒函式的 lpparam 是乙個值;

● 引數 flags 在下面介紹。

當第一次呼叫 queueuserworkitem 時, windows作業系統將建立乙個執行緒池,其中的乙個執行緒將執行 function 函式,函式執行完成後,該執行緒返回執行緒池,等待新的任務。

由於 windows 依賴於該過程來完成執行緒池的功能,因此 function 中不能有任何中止該執行緒的呼叫,如 exitthread。

假如當呼叫 queueuserworkitem 時,沒有可用的執行緒,windows 就可以通過建立額外的執行緒增加執行緒池中線程的數量。

執行緒池中的執行緒的數量是動態的,並且受 windows 的控制,windows 內部的排程演算法決定處理當前執行緒工作負載的最佳方式。

如果知道所要處理的工作需要很長時間才能完成,可以在呼叫 queueuserworkitem 時,將引數的 flags 設定為 wt_executelongfunction ,

這時如果執行緒池中的所有的執行緒都處於忙狀態, 那麼 windows 將自動建立新的執行緒。

windows 執行緒池中的執行緒有兩種型別,一種可以用來處理非同步i/o,另一種則不能。

前者依賴於io完成埠,iocp是一種windows核心物件,它可以將執行緒和 i/o 埠繫結在特定的系統資源上,對帶有完成埠的 i/o 進行處理是乙個複雜的過程。

呼叫 queueuserworkitem 時,需要標識哪些執行緒執行 i/o,哪些執行緒不執行 i/o, 將 queueuserworkitem 中的 flags 設定成 wt_executiondefault,

就可以告訴執行緒池該執行緒不執行非同步 i/o,從而可以對其進行相應的管理;對於執行非同步 i/o 的執行緒,則應該將其 flags 設定為 wt_executeioniothread.

手把手教你完成埠之二 應用中的完成埠簡單模型

首要就是建立完成埠,m hcompletionport 建立完成埠 m hcompletionport createiocompletionport invalid handle value,null,0,0 第一步 等待連線到來 第二步伺服器接收連線之後,將接收連線的socket和完成埠繫結 m ...

二 執行緒狀態

新建狀態 new 用new關鍵字建立乙個執行緒物件後,該執行緒物件就處於新生狀態。處於新生狀態的執行緒有自己的記憶體空間,通過呼叫start方法進入就緒狀態。就緒狀態 runnable 處於就緒狀態的執行緒已經具備了執行條件,但是還沒有被分配到cpu,處於 執行緒就緒佇列 等待系統為其分配cpu。就...

完成埠例子二

tag getqueuedcomple 工作執行緒 dword winapi serverworkerthread lpvoid comlpetionportid 首先檢查套接字上是否發生錯誤,如果發生了則關閉套接字並且清除同套節字相關的 socket inforation 結構體if bytest...