重疊I O詳解

2021-07-07 01:47:42 字數 2931 閱讀 2893

在windows中有乙個api叫readfile 

bool  

readfile( 

handle 

hfile,  

//  

handle 

to  

file 

lpvoid 

lpbuffer,  

//  

data 

buffer  

dword 

nnumberofbytestoread,  

//  

number  

of  

bytes  

to read  

lpdword 

lpnumberofbytesread,  

// number  

of  

bytes  

read  

// buffer 

);  

這個引數設定的是null,那麼readfile這個函式的呼叫一直要到讀取完資料指定的資料後才會返回,如果沒讀取完,就會阻塞在這裡。同樣 

基本上就這樣,。不知道你清楚了沒有,,, 

至於socket裡的重疊io,和這個差不錯,不同的是readfile 

writefile被wsarecv和wsasend所代替了。這其中牽涉到的東西很多,其實有關windows的非同步io機制,是很高深的,所以開始我才推薦你去看《windows2000程式設計內幕》,也可以去看《inside 

windows2000》  

當cpu執行你的**時遇上乙個i/o請求[諸如讀寫檔案之類的],系統產生乙個中斷,讓cpu去完成這個i/o請求,等到完成了以後,系統再次產生乙個中斷讓原先的程式繼續執行。也就說通過中斷保持這兩者間的同步。可以將終端理解為硬體化的訊號量。 

這就是所謂的同步概念,乙個執行緒中只可能同時處理乙個i/o請求 

你要知道,乙個i/o操作是非常耗時的,當你的**掛起後等待i/o完成的這段時間內,你的這個執行緒浪費了n個指令週期。 

如果同時要反覆讀寫大檔案,用同步的效率是很低的。 

為了解決這個問題,當cpu執行你的**時遇上乙個i/o請求後,系統這是為你開一根內部執行緒去處理i/o請求,並且你的執行緒並不掛起,但你可能會覺得如果i/o還沒完成,後續的**就算他讓我執行,我也執行不下去了嘛? 

但如果後續的**和這個i/o操作無關,你就可以以更快的速度之行下去了,而無需等待io請求的完成了 

這也就是非同步了  

你想當你有這樣乙個請求,就是 

readfile(...)  

-1 writefile(...)  

-2  

readfile(...)  

-3 你在程式中如果使用同步的話,那只有當你完成1以後2才會繼續執行,2執行完以後3才會繼續執行。這就是同步。 

當如果使用非同步的話,當系統遇到1時,ok,開一線程給它去完成該io請求,然後系統繼續執行2,3,分別開兩線程。 

1-2-3如果是比較耗時的操作,尤其是運用在網路上,那麼1-2-3這三個io請求是並行的,也就是重疊的。 

重疊i/o就是能夠同時以多個執行緒處理多個i/o,其實你自己開多個執行緒也可以處理多個i/o,當然系統內部優化以後肯定效能要比你的強,呵呵。 

最後提一下重疊模型的缺點,他為每乙個io請求都開了一根執行緒,當同時有1000個請求發生,那麼系統處理執行緒上下文[context]切換也是非常耗時的,所以這也就引發了完成埠模型iocp,用執行緒池來解決這個問題。

檔案重疊i/o例項:

i/o裝置處理必然讓主程式停下來幹等i/o的完成

,對這個問題有

方法一:使用另乙個執行緒進行i/o。這個方案可行,但是麻煩。                即 createthread(…………);建立乙個子執行緒做其他事情。      readfile(^…………);阻塞方式讀資料。

你可以要求作業系統為你傳送資料,並且在傳送完畢時通知你。

這項技術使你的程式在i/o進行過程中仍然能夠繼續處理事務。

你可以獲得執行緒的所有利益,而不需付出什麼痛苦的代價

//功能:從指定檔案的1500位置讀入300個位元組

null);0

memset(&overlap, 0, sizeof(overlap));

//指定檔案位置是

(true)

if (rc)

else

}closehandle(hfile);

return exit_success;

}在實際工作中,若有幾個操作同乙個檔案時

注意,你所使用的event物件必須是乙個manual型的;否則,可能產生競爭條件。

int main()

// 等候所有操作結束

;//隱含條件:當乙個操作完成時,其對應的event物件會被啟用

waitformultipleobjects(max_requests,

ghevents,

true, infinite);

// 收尾操作

int queuerequest(int nindex, dword dwlocation, dword dwamount)

// 處理一些可恢復的錯誤

if ( err == error_invalid_user_buffer ||

err == error_not_enough_quota ||

err == error_not_enough_memory )

// 如果getlasterror()返回的不是以上列出的錯誤,放棄

break;

}return -1;

}程式流程:

1:n個使用者同時讀取乙個檔案的各個部分,且每個使用者對應乙個重疊物件和事件。

2:呼叫waitformultipleobjects(max_requests, ghevents, true, infinite) 當任何乙個使用者的讀操作完成時,函式停止阻塞。並且ghevents中對應於的讀取資料完畢的使用者的事件被啟用。

什麼是重疊I O

在windows中有乙個api bool readfile handle hfile,handle to file lpvoid lpbuffer,data buffer dword nnumberofbytestoread,number of bytes to read lpdword lpnum...

什麼是重疊I O

在windows中有乙個api叫readfile bool readfile handle hfile,handle to file lpvoid lpbuffer,data buffer dword nnumberofbytestoread,number of bytes to read lpdw...

IO重疊的理解

這就是所謂的同步概念,乙個執行緒中只可能同時處理乙個i o請求 你要知道,乙個i o操作是非常耗時的,當你的 掛起後等待i o完成的這段時間內,你的這個執行緒浪費了n個指令週期。如果同時要反覆讀寫大檔案,用同步的效率是很低的。為了解決這個問題,當cpu執行你的 時遇上乙個i o請求後,系統這是為你開...