非同步IO模型和Overlapped結構

ForTechnology發表於2011-08-26

非同步IO模型和Overlapped結構

OVERLAPPED結構主要用於非同步I/O操作,其資料結構定義如下:

typedef struct _OVERLAPPED {
    DWORD Internal;     // 系統保留,存放系統設定的狀態
    DWORD InternalHigh; // 系統保留,存放被傳輸資料的長度
    DWORD Offset;       // 指定檔案的位置,檔案位置是相對檔案開始處的位元組偏移量。
    DWORD OffsetHigh;   // 指定開始傳送資料的位元組偏移量的高位字
    HANDLE hEvent;      // 標識事件,資料傳送完成時把它設為訊號狀態
}OVERLAPPED;

Overlapped I/O模型可以用以下幾種方式實現:

一、核心物件實現
1. 把裝置控制程式碼看作同步物件,ReadFile將裝置控制程式碼設定為無訊號。ReadFile非同步I/O位元組位置必須在OVERLAPPED結構中指定。
2. 完成I/O,設定資訊狀態為有訊號。
3. 通過WaitForSingleObject或WaitForMultipleObject判斷或者非同步裝置呼叫GetOverLappedResult函式。

二、事件核心物件實現
1. Overlapped成員hEven標識事件核心物件。CreateEvent,為每個請求建立一個事件,初始化每個請求的hEvent成員。呼叫WaitForMultipleObject來等其中一個或全部完成。
2. Event物件必須是手動重置,使用自動重置WaitForSingleObject()和 WaitForMultipleObjects()函式不會返回。

關於自動重置事件和手動重置事件
自動重置事件:WaitForSingleObject()和WaitForMultipleObjects()會等待事件到訊號狀態,隨後又自動將其重置為非訊號狀態,保證等待此事件的執行緒中只有一個會被喚醒。
手動重置事件:需要呼叫ResetEvent()才會重置事件。可能有若干個執行緒在等待同一事件,這樣當事件變為訊號狀態時,所有等待執行緒都可以 執行了。 SetEvent()函式用來把事件物件設定成訊號狀態,ResetEvent()把事件物件重置成非訊號狀態,兩者均需事件物件控制程式碼作引數。


三、非同步過程呼叫
在一個Overlapped I/O完成之後,系統呼叫callback回撥函式。系統在裝置控制程式碼有訊號狀態下,才會呼叫回撥函式,傳給它完成I/O請求的錯誤碼,傳輸位元組數和 Overlapped結構的地址。通過下面的五個函式可以設定訊號狀 態:SleepEx,WaitForSingleObjectEx,WaitForMultipleObjectEx,SingalObjectAndWait,MsgWaitForMultipleObjectsEx。

四、完成埠
完成埠(I/O completion)的優點:不會限制handle個數,可處理成千上萬個連線。I/O completion port允許一個執行緒將一個請求暫時儲存下來,由另一個執行緒為它做實際服務。
併發模型與執行緒池:在典型的併發模型中,伺服器為每一個客戶端建立一個執行緒,如果很多客戶同時請求,則這些執行緒都是執行的,那麼CPU就要一個個 切換,CPU花費了更多的時間線上程切換,執行緒卻沒得到很多CPU時間。到底應該建立多少個執行緒比較合適呢,微軟體幫助文件上講應該是2*CPU個。但理 想條件下最好執行緒不要切換,而又能象執行緒池一樣,重複利用。I/O完成埠就是使用了執行緒池。一個執行緒執行任務結束後不會銷燬,而是重新回到執行緒佇列中。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25897606/viewspace-705867/,如需轉載,請註明出處,否則將追究法律責任。

相關文章