這篇文章轉載于CSDN論壇的回帖裡,具體作者忘記裡,不過很感謝作者,感覺對我了解io重疊很有幫助,貼出來供大家參考
當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,用線程池來解決這個問題,我就不多說了。