兩種高效的事件處理模型:Reactor模式和Proactor模式(轉(zhuǎn))

隨著IO多路復(fù)用技術(shù)的出現(xiàn),出現(xiàn)了很多事件處理模式。同步I/O模型通常由Reactor模式實現(xiàn),而異步I/O模型則由Proactor模式實現(xiàn)。

  • Reactor模式:

Reator類圖如上所示,Reactor模式又叫反應(yīng)器或反應(yīng)堆,即實現(xiàn)注冊描述符(Handle)及事件的處理器(EventHandler),當(dāng)有事件發(fā)生的時候,事件多路分發(fā)器(Event Demultiplexer)做出反應(yīng),調(diào)用事件具體的處理函數(shù)(ConcreteEventHandler::handle_event())。

Reator模式的典型啟動過程如下:

  1. 創(chuàng)建Reactor
  2. 注冊事件處理器(Reactor::register_handler())
  3. 調(diào)用事件多路分發(fā)器進(jìn)入無限事件循環(huán)(Reacor:handle_events)
  4. 當(dāng)操作系統(tǒng)通知某描述符狀態(tài)就緒時,事件多路分發(fā)器找出并調(diào)用此描述符注冊的事件處理器。

Reactor模式已經(jīng)被廣泛使用,著名的開源事件庫libevent、libev、libuv都是使用Reactor模式。

Reactor模式的優(yōu)點:

  • 實現(xiàn)相對簡單,對于耗時短的處理場景處理高效;
  • 操作系統(tǒng)可以在多個事件源上等待,并且避免了多線程編程相關(guān)的性能開銷和編程復(fù)雜性;
  • 事件的串行化對應(yīng)用是透明的,可以順序的同步執(zhí)行而不需要加鎖;
  • 事務(wù)分離:將與應(yīng)用無關(guān)的多路分解和分配機(jī)制和與應(yīng)用相關(guān)的回調(diào)函數(shù)分離開來。

Reactor模式的缺點:

Reactor處理耗時長的操作(如文件I/O)會造成事件分發(fā)的阻塞,影響到后續(xù)事件的處理。

因此涉及到文件I/O相關(guān)的操作,需要使用異步I/O,即使用Proactor模式效果更佳。

  • Proactor模式

Proactor模式的類圖如上圖所示,Proactor模式又叫前攝器或主動器模式。它用于實現(xiàn)異步I/O模型,運行流程如下:

1. Initiator主動調(diào)用Asynchronous Operation Processor發(fā)起異步I/O操作,

2. 記錄異步操作的參數(shù)和函數(shù)地址放入完成事件隊列(Completion Event Queue)中

3. Proactor循環(huán)檢測異步事件是否完成。如果完成則從完成事件隊列中取出回調(diào)函數(shù)完成回調(diào)。

Boost庫中的asio就使用了Proactor模式,其底層的異步I/O由操作系統(tǒng)提供,而異步事件的分發(fā)還是由epoll/kequeue/select等實現(xiàn)。

兩者區(qū)別

綜上我們可以發(fā)現(xiàn)Reactor模式和Proactor模式的主要區(qū)別:

1. Reactor實現(xiàn)同步I/O多路分發(fā),Proactor實現(xiàn)異步I/O分發(fā)。

如果只是處理網(wǎng)絡(luò)I/O單線程的Reactor尚可處理,但如果涉及到文件I/O,單線程的Reactor可能被文件I/O阻塞而導(dǎo)致其他事件無法被分發(fā)。所以涉及到文件I/O最好還是使用Proactor模式,或者用多線程模擬實現(xiàn)異步I/O的方式。

2. Reactor模式注冊的是文件描述符的就緒事件,而Proactor模式注冊的是完成事件。

即Reactor模式有事件發(fā)生的時候要判斷是讀事件還是寫事件,然后用再調(diào)用系統(tǒng)調(diào)用(read/write等)將數(shù)據(jù)從內(nèi)核中拷貝到用戶數(shù)據(jù)區(qū)繼續(xù)其他業(yè)務(wù)處理。

而Proactor模式一般使用的是操作系統(tǒng)的異步I/O接口,發(fā)起異步調(diào)用(用戶提供數(shù)據(jù)緩沖區(qū))之后操作系統(tǒng)將在內(nèi)核態(tài)完成I/O并拷貝數(shù)據(jù)到用戶提供的緩沖區(qū)中,完成事件到達(dá)之后,用戶只需要實現(xiàn)自己后續(xù)的業(yè)務(wù)處理即可。

3. 主動和被動

Reactor模式是一種被動的處理,即有事件發(fā)生時被動處理。而Proator模式則是主動發(fā)起異步調(diào)用,然后循環(huán)檢測完成事件。

最后我們知道linux系統(tǒng)提供的異步I/O,只支持O_DIRECT,不能帶緩存。因此出現(xiàn)了開源庫libeio,它和Linux的異步I/O一樣也是用多線程模擬,但是更高效。下圖是libeio的異步I/O實現(xiàn),是不是很像Proactor模式啊。

轉(zhuǎn)自:https://www.cnblogs.com/bitkevin/p/5724410.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容