重疊I/O技術

  在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,用線程池來解決這個問題,我就不多說了。
發佈了24 篇原創文章 · 獲贊 20 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章