數年前做一個項目時,參考了《Programming Server-Side Application For Microsoft Windows 2000》一書,該書作者就是大名鼎鼎的Jeffery Rechard,《Windows核心編程》的作者。當時為工作群組內其他人翻譯了第二章。時至今日,將這個老文發出來為我的部落格充數,也希望對別人有所協助。
第二章 裝置
I/O
與線程間通訊 我無法完全表達本章的重要性,本章覆蓋了關於實現高效能,可伸縮應用程式的兩個本質性主題:裝置I/O和線程間通訊。一個可伸縮的應用程式在處理大量並發事務時,應像處理小量並發事務時一樣高效。對於服務應用,典型的操作是處理不週期性用戶端請求,並且該請求所需要的處理能力不能預見。這些請求經常來自於I/O裝置,例如網路介面卡;通常請求處理接著會做一些附加的I/O操作,比如磁碟檔案訪問等等。 對於微軟的Windows應用程式,線程是分拆工作的最好機制。每一個線程被分配給一個處理器,這樣具有多處理器的機器就能夠同時執行多個操作,以提高輸送量。當某個線程提交一個裝置I/O請求時,該線程將被暫時性掛起直到裝置完成了I/O請求。這種掛起嚴重降低了效能,因為此時線程不能做其他有用的工作,如初始化另一個用戶端請求並進行處理。因此,簡單的說,你應該保持線程始終在忙的狀態,做有用的工作,而不是簡單的掛起。 要保持線程忙碌,需要進行線程間通訊以使線程間彼此瞭解將要進行的操作。微軟已經花費了數年時間在這一領域進行研究和測試,而且發展出很好的機制來進行線程間通訊。這種機制稱為I/O完成連接埠(I/O completion port),它能夠幫你建立高效能的,可伸縮的應用。一個例子是Windows 2000中新的任務核心對象(Job kernel object):當一個任務對象監視到有操作需要進行處理,它會發送一個通知事件給一個I/O完成連接埠。 JobLab應用程式的樣本,可以從《Programming Application For microsoft Windows, Forth Edition》(Windows核心編程)得到,該例子描述了如何使I/O完成連接埠和任務對象一起工作。 根據多年的Windows開發經驗,我發現越來越多的人在使用I/O完成連接埠,我感覺每一個Windows開發人員必須透徹理解I/O完成連接埠是如何工作的。本書中許多樣本程式都使用了I/O完成連接埠。即使我在本章關於裝置I/O的主題中闡述I/O完成連接埠,需要注意的是:I/O完成連接埠並非是完全針對裝置I/O的,簡單的說,它是一個公認的用於應付無限的請求處理的處理序間通訊機制。
基於以上的吹捧,你可能認為我是I/O完成連接埠的BIG FANS。我希望在本章結束後,你也成為和我一樣的粉絲。在瞭解I/O完成連接埠的細節前,我將描述Windows原來是如何向開發人員提供線程間通訊和裝置I/O支援的。這將帶給你大量的關於I/O完成連接埠的體驗。在本章的結尾,"I/O完成連接埠"一節中,我將詳細討論I/O完成連接埠。