日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

两种高性能 I/O 设计模式 Reactor 和 Proactor

發(fā)布時(shí)間:2025/3/21 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 两种高性能 I/O 设计模式 Reactor 和 Proactor 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Reactor 和 Proactor 是基于事件驅(qū)動(dòng),在網(wǎng)絡(luò)編程中經(jīng)常用到兩種設(shè)計(jì)模式。

曾經(jīng)在一個(gè)項(xiàng)目中用到了網(wǎng)絡(luò)庫 libevent,也學(xué)習(xí)了一段時(shí)間,其內(nèi)部實(shí)現(xiàn)所用到的就是 Reactor,所知道的還有 ACE;Proactor 模式的庫有 Boost.Asio,ACE,暫時(shí)沒有用過。但我也翻閱了一些文檔,理解了它的實(shí)現(xiàn)方法。下面是我在學(xué)習(xí)這兩種設(shè)計(jì)模式過程的筆記。

Reactor

Reactor,即反應(yīng)堆。Reactor 的一般工作過程是首先在 Reactor?中注冊(cè)(Reactor)感興趣事件,并在注冊(cè)時(shí)候指定某個(gè)已定義的回調(diào)函數(shù)(callback);當(dāng)客戶端發(fā)送請(qǐng)求時(shí),在 Reactor?中會(huì)觸發(fā)剛才注冊(cè)的事件,并調(diào)用對(duì)應(yīng)的處理函數(shù)。在這一個(gè)處理回調(diào)函數(shù)中,一般會(huì)有數(shù)據(jù)接收、處理、回復(fù)請(qǐng)求等操作。

libevent 采用的就是 Reactor?的設(shè)計(jì)思想。其?Reactor?的中心思想是眾所周知的 I/O 多路復(fù)用:select,poll,epoll,kqueue 等.libevent 精彩的將定時(shí)事件,信號(hào)處理,I/O 事件結(jié)合在在一起,也就是說用戶同時(shí)在 Reactor?中注冊(cè)上述三類事件。遺憾的是,libevent 不支持多線程,也就是說它同步處理請(qǐng)求,導(dǎo)致不能處理大量的請(qǐng)求;這樣并不是說 Reactor?實(shí)現(xiàn)的網(wǎng)絡(luò)庫都不支持多線程,而是 libevent 本身的原因,我們也可以通過修改讓 ilbevent 支持多線程,并發(fā)處理多個(gè)請(qǐng)求。

下面是 libevent 的一段代碼,大概能夠說明 Reactor?工作模式:

/*accept callback function.*/ void accept_callback(int fd, ?????????????????????shortev,void *arg) { ????...... } ...... struct event accept_event; event_set(&accept_event, ????????socketlisten, ????????EV_READ|EV_PERSIST, ????????accept_callback, ????????NULL); event_add(&accept_event, ????????NULL); event_dispatch();

Proactor

從上面 Reactor?模式中,發(fā)現(xiàn)服務(wù)端數(shù)據(jù)的接收和發(fā)送都占用了用戶狀態(tài)(還有一種內(nèi)核態(tài)),這樣服務(wù)器的處理操作就在數(shù)據(jù)的讀寫上阻塞花費(fèi)了時(shí)間,節(jié)省這些時(shí)間的辦法是借助操作系統(tǒng)的異步讀寫;異步讀寫在調(diào)用的時(shí)候可以傳遞回調(diào)函數(shù)或者回送信號(hào),當(dāng)異步操作完畢,內(nèi)核會(huì)自動(dòng)調(diào)用回調(diào)函數(shù)或者發(fā)送信號(hào)。Proactor 就是這么做的,所以很依賴操作系統(tǒng)。來一幅 UML:

和時(shí)序圖:

注:這兩幅美艷的圖片來自?Proactor.doc,下面會(huì)提到.

Proactor?的實(shí)現(xiàn)主要有三個(gè)部分:異步操作處理器,Proactor 和 事件處理函數(shù)。其中:

- 異步操作處理器,很依賴操作系統(tǒng)的異步處理機(jī)制,如若操作系統(tǒng)沒有實(shí)現(xiàn),我們可以自行模擬,即開專門的數(shù)據(jù)讀寫線程,數(shù)據(jù)讀寫完畢觸發(fā)相應(yīng)的時(shí)間(如果有注冊(cè)的話); - Proactor,會(huì)接收異步操作的提醒,調(diào)用相應(yīng)的事件處理函數(shù),它有自己的 event loop; - 事件處理函數(shù),事件觸發(fā),執(zhí)行操作;

曾經(jīng)看過 Proactor.doc,作者是 Douglas C.?Schmidt,你可以在這里閱讀此文檔。里面的關(guān)于 Proactor?的講解很精彩,部分摘抄和自己的理解如下:當(dāng)連接 web 服務(wù)器時(shí):

  • web 服務(wù)器指定(1)接收器,此接收器相當(dāng)于服務(wù)器的客戶端,它可以啟動(dòng)異步的 accept 操作;
  • 接收器調(diào)用操作系統(tǒng)上的異步接收操作(2),并傳遞自己和 Proactor?的引用;異步接收操作結(jié)束后,前者用作事件處理函數(shù),后者會(huì)回過頭來分發(fā)事件;注:傳遞 Proactor?是為了讓操作系統(tǒng)通知正確的 Proactor,可能會(huì)存在多個(gè) Proactor;傳遞接收器自己是為了在異步接收操作結(jié)束后 Proactor?能調(diào)用正確的事件處理函數(shù),以下同理。
  • web 服務(wù)器調(diào)用 Proactor?的事件循環(huán);(3)
  • web 瀏覽器連接 web 服務(wù)器;(4)
  • 異步接收操作結(jié)束后,操作系統(tǒng)產(chǎn)生事件(通過回調(diào)或者信號(hào))并通知 Proactor(5),Proactor 收到后會(huì)調(diào)用相應(yīng)的事件處理函數(shù),即交由接收器處理;(6)
  • 接收器生成 HTTP 處理器,執(zhí)行操作;(7)
  • HTTP 處理器解析事件,啟動(dòng)異步讀操作(8),獲取來自瀏覽器的 GET 請(qǐng)求。同樣,HTTP 處理器傳遞自己和 Proactor?的引用;
  • web 服務(wù)器的控制權(quán)交還回 Proactor?的事件循環(huán)。(9)

接收 GET 請(qǐng)求過后,會(huì)處理數(shù)據(jù):

  • 瀏覽器發(fā)送(1)一個(gè) HTTP GET 請(qǐng)求;
  • 異步讀操作結(jié)束后,操作系統(tǒng)會(huì)通知 Proactor,Proactor 分發(fā)給事件處理函數(shù);(2,3)
  • 事件處理器解析請(qǐng)求。(4)2-4 步驟會(huì)重復(fù),指導(dǎo)所有的數(shù)據(jù)都接收為止;
  • 事件處理器產(chǎn)生答復(fù)數(shù)據(jù);(5)
  • HTTP 處理器啟動(dòng)異步寫操作(6),傳輸應(yīng)答數(shù)據(jù),同樣的這里還會(huì)傳遞處理器自己和 Proactor;
  • 異步寫操作結(jié)束,操作系統(tǒng)通知 Proactor(7),Proactor 分發(fā)給事件處理函數(shù)(8)。6-8 步驟會(huì)重復(fù)直到所有的數(shù)據(jù)寫完為止。至此,一個(gè)請(qǐng)求回復(fù)完成。

總結(jié)

相比網(wǎng)絡(luò)編程中最簡單的思路模式:bind,listen,accept,read,server operator,write,Reactor 和 Proactor 是兩種高性能的設(shè)計(jì)模式,掌握此兩種模式,有助于理解一些網(wǎng)絡(luò)庫的工作流程。此文提到了兩種設(shè)計(jì)模式,但沒有一些技術(shù)細(xì)節(jié),譬如多線程同步。如果在 Reactor 中支持多線程,或多個(gè)線程共享一個(gè) Proactor,線程的同步問題就來了。共享一篇印象筆記關(guān)于線程的綜合討論:這里.

《Comparing Two High-Performance I/O Design Patterns》提到一個(gè)將 Reactor 模擬 Proactor 而不借助操作系統(tǒng)異步機(jī)制的方法:同樣在 Reactor 注冊(cè)感興趣的事件(比如讀),當(dāng)事件發(fā)生時(shí),執(zhí)行非阻塞的讀,讀畢即才調(diào)用數(shù)據(jù)處理——假異步。

最后,實(shí)踐出真知。歡迎討論。

參考:

- Proactor.pdf,http://www.laputan.org/pub/sag/proactor.pdf

- 《Comparing Two High-Performance I/O Design Patterns》,http://www.artima.com/articles/io_design_patterns.html

- 《libevent源碼深度剖析》,http://blog.csdn.net/sparkliang/article/details/4957667

- 《?IO - 同步,異步,阻塞,非阻塞 (亡羊補(bǔ)牢篇)》,http://blog.csdn.net/historyasamirror/article/details/5778378

搗亂 2013-08-21

總結(jié)

以上是生活随笔為你收集整理的两种高性能 I/O 设计模式 Reactor 和 Proactor的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。