windows下異步IO


所謂異步IO,就是當線程向設備驅動程序發送一個IO請求后,線程不會等待處理,而是繼續執行,設備驅動程序去完成實際的IO操作,再通過其他方式通知程序

注意:

如果我們發送一個異步IO請求給設備驅動程序,設備驅動程序不一定會以異步處理IO請求,有時候會選擇以同步的方式來請求。當我們IO請求發送后,操作系統檢查我們的數據是否在系統的緩存中,如果在緩存中,那么操作系統不會把這個請求發送給設備驅動程序,而會直接將數據從高速緩存中復制給我們的程序,直接完成IO請求

 

如果IO操作是以同步方式執行的,那么ReadFile和WriteFile將會返回非0值,如果是以異步的,或者發生了錯誤,那么將會返回FALSE

1.OVERLAPPED

OVERLAPPED即重疊的,也就是說一個線程可以在讀的時候做其他的事情,具體我在之前有寫過這個

http://www.cnblogs.com/linyilong3/archive/2012/05/03/2480451.html

之前一直不知道的一點是Offset和OffsetHight,一直都是設置為0,然后緩沖區開到最大,今天看windows核心編程發現這兩個數字組成了一個64位的數字,假設我們把Offset設置為10,OffsetHight設置為0,那么在讀取數據的時候將會從10開始讀取

 

OVERLAPPED IO操作每次都需要指定操作的位置,在同步IO中,我們在進行完一個IO后,文件的都會移動偏移指針,下次我們再次對文件進行IO操作的時候,文件將會從上一次操作結束的地方開始,但是在異步IO中,我們如果發起兩個IO操作,可能是第二個IO操作先執行並且完成,這個時候第二個IO請求可能從起始位置開始,第一個則從第二個IO請求結束的位置開始操作,這個時候就會造成混亂

 

等待IO完成通知:

1.WaitForSingleObject,觸發設備內核對象

 

2.可以利用OVERLAPPED里面的hEvent,這在windows核心編程里面的示例主要是在有多個IO請求的時候,比如一個讀一個些,WaitForSingleObject無法知道究竟是哪個完成,可以為每個事件創建單獨的hEvent

 

2.可提醒IO


windows核心編程上是說可提醒IO非常糟糕,應該避免使用,他是使用ReadFileEx或者WriteFileEx,這兩個函數比原來的函數多了一個參數,是一個函數指針,這個函數是當IO請求完成后需要回調的函數,但是這些回調函數並不回立即調用,而是要等到線程將自己設置為可提醒狀態,這6個函數:SleepEx,WaitForSingleObjectEx,WaitforMultipleObjectsEx,SignalObjectAndWait,GetQueuedCompletionStatusEx,MsgWaitForMultipleObjectsEx,當線程進入可提醒狀態的時候,並且IO請求隊列已經有完成的了,操作系統將會開始調用這些回調函數,直到完成隊列里面的沒有消息了,那么我們對 可提醒調用的函數將會返回,我們可以利用這個特性,來讓暫停執行的線程繼續往下執行

 

劣勢:

必須有一個回調函數,增加代碼復雜度,因為這些回調函數沒有足夠的與某個問題有關的上下文信息,所以一些信息只能放到全局變量中(原本我想可以利用C++的類解決這個問題,但是后來想了下,如果局部變量要變成類成員變量,那么會增加類的復雜度)

 

線程,發出IO請求的線程同時對完成通知作出處理,如果一個線程發出多個請求,就必須處理多個請求,負載不均衡,程序的伸縮性不太好

 

完成端口:

所謂完成端口,就是由用戶創建一個端口,並且將設備的HANDLE與這個端口關聯,這樣當IO完成后,將會通知這個端口,再由這個端口進行處理

 

而完成端口則會根據用戶指定的線程數來創建線程,一般是CPU*2的數量,因為創建過多那么將會把大部分時間都花在線程上下文切換上面

 

完成端口總共保存四個列表,一個是IO完成隊列,一個是等待線程隊列,一個是釋放線程列表還有已暫停線程的列表,暫停線程列表和等待線程隊列的不同是暫停線程列表是利用函數把線程掛起,如果用戶喚醒了這個線程那么這個線程將會被加入釋放列表,而等待線程隊列是用戶調用GetQueuedCompletionStatus來等待IO消息,用戶也可以通過PostQueuedCompletionStatus來將線程加入IO完成隊列

 

如果不需要將IO請求添加到IO完成端口的隊列,可以Overlapped.hEvent = (HANDLE)((DWORD_PTR)Overlapped.hEvent | 1)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM