非同步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...