在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
lpoverlapped lpoverlapped // overlapped buffer
);
如果我們在createfile的時候沒有使用file_flag_overlapped 標誌,同時在調用readfile的時候把lpoverlapped lpoverlapped 這個參數設定的是null,那麼readfile這個函數的調用一直要到讀取完資料指定的資料後才會返回,如果沒讀取完,就會阻塞在這裡。同樣 ,writefile和readfile都是這樣的。這樣在讀寫大檔案的時候,我們很多時間都浪費在等待readfile和writefile的返回上面。如果readfile和writefile是往管道裡讀寫資料,那麼有可能阻塞得更久,導致程式效能下降。為瞭解決這個問題,windows引進了重疊io的概念,同樣是上面的readfile和writefile,如果在createfile的時候設定了file_flag_overlapped ,那麼在調用readfile和writefile的時候就可以給他們最後一個參數傳遞一個overlapped結構。這樣readfile或者writefile的調用馬上就會返回,這時候你可以去做你要做的事,系統會自動替你完成readfile或者writefile,在你調用了readfile或者writefile後,你繼續做你的事,系統同時也幫你完成readfile或writefile的操作,這就是所謂的重疊。使用重疊io還有一個好處,就是你可以同時發出幾個readfile或者writefile的調用,然後用waitforsingleobject或者waitformultipleobjects來等待作業系統的操作完成通知,在得到通知訊號後,就可以用getoverlappedresult來查詢io調用的結果。
基本上就這樣,。不知道你清楚了沒有,,,
至於socket裡的重疊io,和這個差不錯,不同的是readfile writefile被wsarecv和wsasend所代替了。這其中牽涉到的東西很多,其實有關windows的非同步io機制,是很高深的,所以開始我才推薦你去看《windows2000編程內幕》,也可以去看《inside windows2000》
發表者:nonocast
當cpu執行你的代碼時遇上一個i/o請求[諸如讀寫檔案之類的],系統產生一個中斷,讓cpu去完成這個i/o請求,等到完成了以後,系統再次產生一個中斷讓原先的程式繼續運行。也就說通過中斷保持這兩者間的同步。可以將終端理解為硬體化的訊號量。
這就是所謂的同步概念,一個線程中只可能同時處理一個i/o請求
你要知道,一個i/o操作是非常耗時的,當你的代碼掛起後等待i/o完成的這段時間內,你的這個線程浪費了n個指令周期。
如果同時要反覆讀寫大檔案,用同步的效率是很低的。
為瞭解決這個問題,當cpu執行你的代碼時遇上一個i/o請求後,系統這是為你開一根內部線程去處理i/o請求,並且你的線程並不掛起,但你可能會覺得如果i/o還沒完成,後續的代碼就算他讓我執行,我也執行不下去了嘛?
如果下面的代碼和這個i/o操作有關的話,那麼它就要等一等,等到這個i/o操作完成,通過在一個線程中調用waitformultiobject()和getoverlappedresult()就可以得到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,當然系統內部最佳化以後肯定效能要比你的強,呵呵。
我只是簡單的說了一下重疊[overlapped]沒從代碼的角度給你分析。希望你能對重疊io有所理解。看看windows網路編程,上面不是有模型嘛
最後提一下重疊模型的缺點,他為每一個io請求都開了一根線程,當同時有1000個請求發生,那麼系統處理線程上下文[context]切換也是非常耗時的,所以這也就引發了完成連接埠模型iocp,用線程池來解決這個問題,我就不多說了。
歡迎您使用http://Blogmove.cn提供的"部落格搬家"和"博文三窟"服務.