非同步裝置I O 請求加入佇列與接受完成通知

2021-06-18 20:38:16 字數 2502 閱讀 1431

非同步i/o請求:  當執行緒發出乙個非同步i/o請求時,這個請求被傳遞給裝置驅動程式,由後者負責完成實際的i/o操作。 當驅動程式在等待裝置響應的時候,應用程式的執行緒並沒有因為等待i/o請求完成而被掛起,執行緒會繼續執行並執行其他任務。

將非同步i/o請求加入佇列,有驅動程式完成對列中 i/o 請求的處理,並通知應用程式i/o操作已完成。

非同步方式訪問裝置:

將i/o請求加入到裝置驅動程式的佇列:

dword internal; //[out] error code

dword internalhigh; //[out] number of bytes transferred

dword offset; //[int] low 32it offset

dword offsethigh; //[int] high 32it offset

handle hevent; //[int] evernt handle or data

其中offset offsethigh 用於 表明訪問檔案應從**開始i/o操作。

每個檔案核心物件都有與之相關的檔案指標,用於表明讀取起始位置。每次操作完成後,os會自動更新檔案指標。

同步i/o時 會接著上次的檔案指標,非同步i/o 無先後順序,所以需指明其實偏移量。

非同步裝置i/o注意事項:

1. 驅動程式不必以先入先出的方式來處理佇列中的i/o請求 例

byte bbuffer[100];

readfile ( hfile, bbuffer, 100, null, &o1 );

writefile ( hfile, bbuffer, 100, null, &o2 );

驅動程式可能先寫 後讀取。

提高效率為準:例 為了降低磁頭的移動和尋道時間。尋找物理磁碟上相鄰的請求。

2.用正確的方式檢錯

請求i/o 以同步方式執行時, readfile ,writefile 會返回非零值。  非同步方式時,出錯時 返回false, 需getlasterror判斷,是出錯還是 加入了佇列,為處理完error_io_pending。

取消佇列中的裝置i/o請求:

接受i/o請求完成通知

windows提供4中不同方式來接受完成通知 技術

簡介觸發裝置核心物件

乙個執行緒發出i/o請求,另乙個執行緒出結果進行處理。

當向乙個裝置同時發出多個i/o請示時,則無能為力。因為裝置只有乙個,其處於激發狀態與否,只能表示乙個請求的狀態。

觸發事件核心物件

乙個執行緒發出i/o請求,另乙個執行緒出結果進行處理。

可以向乙個裝置同時發出多個i/o請求(為每個請求建立相應的事件物件)

使用可提醒i/o

可以向乙個裝置同時發出多個i/o請求,發出請求的執行緒處理結果

使用i/o完成埠

乙個執行緒發出i/o請求,另乙個執行緒出結果進行處理。

可以向乙個裝置同時發出多個i/o請求

例:1.觸發裝置核心物件

byte bbuffer[100];

o.offset = 345;

bool breaddone = readfile(hfile, bbuffer, 100, null, &o);

dword dwerror = getlasterror();

if (!breaddone && (dwerror == error_io_pending))

if(breaddone)

else

2.觸發事件核心物件

當需要檢測i/o請求的完成狀態時,可以通過呼叫waitformultipleobjects,並傳入相關聯的時間控制代碼 即可。

byte breadbuffer[100];

o.offset = 0;

oread.hevent = createevent(...);

readfile(hfile, breadbuffer, 100, null, &oread);

byte bwritebuffer[100] = ;

o.offset = 0;

owrite.hevent = createevent(...);

writefile(hfile, breadbuffer, _countof(bwritebuffer), null, &owrite);

....

handle h[2];

h[0] = oread.hevent;

h[1] = owrite.hevent;

dword dw = waitformultipleobjects( 2, h, false, infinite);

switch(dw - wait_object_0)

case 0://read completed

case 1://write completed

}

Linux裝置驅動中的非同步通知和非同步IO

前面兩章分別提到io模型中的阻塞與非阻塞linux驅動 六 裝置驅動中的阻塞與非阻塞io,io多路復用驅動中輪詢操作實現,這一章我們再來看看非同步io,這樣,io模型就可以都搞定了。回顧一下在應用程式中使用非同步io的步驟 1,應用程式 1 設定非同步標誌位 int flags fcntl fd,f...

佇列 C000 LC 最近的請求次數(出入隊)

寫乙個 recentcounter 類來計算最近的請求。它只有乙個方法 ping int t 其中 t 代表以毫秒為單位的某個時間。返回從 3000 毫秒前到現在的 ping 數。任何處於 t 3000,t 時間範圍之內的 ping 都將會被計算在內,包括當前 指 t 時刻 的 ping。保證每次對...

Linux裝置驅動之阻塞I O與非同步通知

阻塞與非阻塞訪問是 i o 操作的兩種不同模式,前者在 i o 操作暫時不可進行時會讓程序睡眠,後者則不然。在裝置驅動中阻塞 i o一般基於等待佇列來實現,等待佇列可用於同步驅動中事件發生的先後順序。使用非阻塞 i o 的應用程式也可借助輪詢函式來查詢裝置是否能立即被訪問,使用者空間呼叫 selec...