Reactor 和 Proactor 是基于事件驅(qū)動,在網(wǎng)絡編程中經(jīng)常用到兩種設(shè)計模式。 曾經(jīng)在一個項目中用到了網(wǎng)絡庫 libevent,也學習了一段時間,其內(nèi)部實現(xiàn)所用到的就是 Reactor,所知道的還有 ACE;Proactor 模式的庫有 Boost.Asio,ACE,暫時沒有用過。但我也翻閱了一些文檔,理解了它的實現(xiàn)方法。下面是我在學習這兩種設(shè)計模式過程的筆記。 ReactorReactor,即反應堆。Reactor 的一般工作過程是首先在 Reactor 中注冊(Reactor)感興趣事件,并在注冊時候指定某個已定義的回調(diào)函數(shù)(callback);當客戶端發(fā)送請求時,在 Reactor 中會觸發(fā)剛才注冊的事件,并調(diào)用對應的處理函數(shù)。在這一個處理回調(diào)函數(shù)中,一般會有數(shù)據(jù)接收、處理、回復請求等操作。 libevent 采用的就是 Reactor 的設(shè)計思想。其 Reactor 的中心思想是眾所周知的 I/O 多路復用:select,poll,epoll,kqueue 等.libevent 精彩的將定時事件,信號處理,I/O 事件結(jié)合在在一起,也就是說用戶同時在 Reactor 中注冊上述三類事件。遺憾的是,libevent 不支持多線程,也就是說它同步處理請求,導致不能處理大量的請求;這樣并不是說 Reactor 實現(xiàn)的網(wǎng)絡庫都不支持多線程,而是 libevent 本身的原因,我們也可以通過修改讓 ilbevent 支持多線程,并發(fā)處理多個請求。 下面是 libevent 的一段代碼,大概能夠說明 Reactor 工作模式:
Proactor從上面 Reactor 模式中,發(fā)現(xiàn)服務端數(shù)據(jù)的接收和發(fā)送都占用了用戶狀態(tài)(還有一種內(nèi)核態(tài)),這樣服務器的處理操作就在數(shù)據(jù)的讀寫上阻塞花費了時間,節(jié)省這些時間的辦法是借助操作系統(tǒng)的異步讀寫;異步讀寫在調(diào)用的時候可以傳遞回調(diào)函數(shù)或者回送信號,當異步操作完畢,內(nèi)核會自動調(diào)用回調(diào)函數(shù)或者發(fā)送信號。Proactor 就是這么做的,所以很依賴操作系統(tǒng)。來一幅 UML: 和時序圖: 注:這兩幅美艷的圖片來自 Proactor.doc,下面會提到. Proactor 的實現(xiàn)主要有三個部分:異步操作處理器,Proactor 和 事件處理函數(shù)。其中: - 異步操作處理器,很依賴操作系統(tǒng)的異步處理機制,如若操作系統(tǒng)沒有實現(xiàn),我們可以自行模擬,即開專門的數(shù)據(jù)讀寫線程,數(shù)據(jù)讀寫完畢觸發(fā)相應的時間(如果有注冊的話); - Proactor,會接收異步操作的提醒,調(diào)用相應的事件處理函數(shù),它有自己的 event loop; - 事件處理函數(shù),事件觸發(fā),執(zhí)行操作; 曾經(jīng)看過 Proactor.doc,作者是 Douglas C. Schmidt,你可以在這里閱讀此文檔。里面的關(guān)于 Proactor 的講解很精彩,部分摘抄和自己的理解如下:當連接 web 服務器時:
接收 GET 請求過后,會處理數(shù)據(jù):
總結(jié)相比網(wǎng)絡編程中最簡單的思路模式:bind,listen,accept,read,server operator,write,Reactor 和 Proactor 是兩種高性能的設(shè)計模式,掌握此兩種模式,有助于理解一些網(wǎng)絡庫的工作流程。此文提到了兩種設(shè)計模式,但沒有一些技術(shù)細節(jié),譬如多線程同步。如果在 Reactor 中支持多線程,或多個線程共享一個 Proactor,線程的同步問題就來了。共享一篇印象筆記關(guān)于線程的綜合討論:這里. 《Comparing Two High-Performance I/O Design Patterns》提到一個將 Reactor 模擬 Proactor 而不借助操作系統(tǒng)異步機制的方法:同樣在 Reactor 注冊感興趣的事件(比如讀),當事件發(fā)生時,執(zhí)行非阻塞的讀,讀畢即才調(diào)用數(shù)據(jù)處理——假異步。 最后,實踐出真知。歡迎討論。 參考: - Proactor.pdf,http://www./pub/sag/proactor.pdf - 《Comparing Two High-Performance I/O Design Patterns》,http://www./articles/io_design_patterns.html - 《libevent源碼深度剖析》,http://blog.csdn.net/sparkliang/article/details/4957667 - 《 IO - 同步,異步,阻塞,非阻塞 (亡羊補牢篇)》,http://blog.csdn.net/historyasamirror/article/details/5778378 |
|