通常地,I/O多路複用機制都依賴於一個事件多路分離器(Event Demultiplexer)。分離器對象可未來自事件源的I/O事件分離出來,並分發到對應的read/write事件處理器(Event Handler)。開發人員預先註冊須要處理的事件及其事件處理器(或回調函數);事件分離器負責將請求事件傳遞給事件處理器。兩個與事件分離器有關的模式是Reactor和Proactor。Reactor模式採用同步IO,而Proactor採用異步IO。linux
在Reactor中,事件分離器負責等待文件描述符或socket爲讀寫操做準備就緒,而後將就緒事件傳遞給對應的處理器,最後由處理器負責完成實際的讀寫工做。編程
在Proactor模式中,處理器--或者兼任處理器的事件分離器,只負責發起異步讀寫操做。IO操做自己由操做系統來完成。傳遞給操做系統的參數須要包括用戶定義的數據緩衝區地址 和 數據大小,操做系統才能從中獲得寫出操做所需數據,或寫入從socket讀到的數據。事件分離器捕獲IO操做完成事件,而後將事件傳遞給對應處理器。windows
好比,在windows上,處理器發起一個異步IO操做,再由事件分離器等待IOCompletion事件。典型的異步模式實現,都創建在操做系統支持異步API的基礎之上,咱們將這種實現稱爲「系統級」異步或「真」異步,由於應用程序徹底依賴操做系統執行真正的IO工做。服務器
Reactor反應器:多線程
「反應」即「倒置」,「控制逆轉」,具體事件處理程序不調用反應器,而是由反應器分配一個具體事件處理程序,具體事件處理程序對某個指定的事件發生作出反應;這種控制逆轉又稱爲「好萊塢法則」(不要調用我,讓我來調用你)併發
Proactor主動器:異步
應用程序啓動,調用異步操做處理器提供的異步操做接口函數,調用以後應用程序和異步操做處理就獨立運行;應用程序能夠調用新的異步操做,而其它操做能夠併發進行; 應用程序啓動Proactor主動器,進行無限的事件循環,等待完成事件到來; 異步操做處理器執行異步操做,完成後將結果放入到完成事件隊列; 主動器從完成事件隊列中取出結果,分發到相應的完成事件回調函數處理邏輯中;socket
步驟 2) 發」已經可讀」事件發給事先註冊的事件處理者或者回調 ( Reactor 要作的)函數
步驟 3) 讀數據 (用戶代碼要作的)性能
步驟 4) 處理數據 (用戶代碼要作的)
步驟 1) 等待事件 (Proactor 的工做)
步驟 2) 讀數據(看,這裏變成成了讓 Proactor 作這個事情,可用用操做系統的異步io函數,也能夠用一個主線程來模擬異步io)
步驟 3) 把數據已經準備好的消息給用戶處理函數,即事件處理者(Proactor 要作的)
步驟 4) 處理數據 (用戶代碼要作的)
以主動寫爲例:
Reactor將handle放到select(),等待可寫就緒,而後調用write()寫入數據;寫完處理後續邏輯;
Proactor調用aoi_write後馬上返回,由內核負責寫操做,寫完後調用相應的回調函數處理後續邏輯;
能夠看出,Reactor被動的等待指示事件的到來並作出反應;它有一個等待的過程,作什麼都要先放入到監聽事件集合中等待handler可用時再進行操做;
Proactor直接調用異步讀寫操做,調用完後馬上返回;
Reactor實現了一個被動的事件分離和分發模型,服務等待請求事件的到來,再經過不受間斷的同步處理事件,從而作出反應;
Proactor實現了一個主動的事件分離和分發模型;這種設計容許多個任務併發的執行,從而提升吞吐量;並可執行耗時長的任務(各個任務間互不影響)
Reactor實現相對簡單,對於耗時短的處理場景處理高效;
操做系統能夠在多個事件源上等待,而且避免了多線程編程相關的性能開銷和編程複雜性;
事件的串行化對應用是透明的,能夠順序的同步執行而不須要加鎖;
事務分離:將與應用無關的多路分解和分配機制和與應用相關的回調函數分離開來,
Proactor性能更高,可以處理耗時長的併發場景;
Reactor處理耗時長的操做會形成事件分發的阻塞,影響到後續事件的處理;
Proactor實現邏輯複雜;依賴操做系統對異步的支持,目前實現了純異步操做的操做系統少,實現優秀的如windows IOCP,但因爲其windows系統用於服務器的侷限性,目前應用範圍 較小;而Unix/Linux系統對純異步的支持有限,應用事件驅動的主流仍是經過select/epoll來實現
(Linux有對aio的支持,能夠參照這篇文章:http://www.lenky.info/archives/2013/01/2183 linux native AIO與eventfd、epoll的結合使用);
Reactor:同時接收多個服務請求,而且依次同步的處理它們的事件驅動程序;
Proactor:異步接收和同時處理多個服務請求的事件驅動程序;