【死磕 NIO】— Proactor模式是什么?很牛逼嗎?


大家好,我是大明哥。

上篇文章我們分析了高性能 IO模型Reactor模式,了解了什么是Reactor 模式以及它的三種常見的模式,這篇文章,大明再介紹另外一種高性能IO模型: Proactor

為什么是 Proactor 模式

上篇文章 【死磕 NIO】— Reactor 模式就一定意味着高性能嗎?大明哥分析了 Reactor模式,我們知道Reactor性能確實非常高,適合高並發場景,但是它依然存在一個問題,那就是它是 同步IO。同步IO會有一個什么問題呢?同步IO需要線程自己等待內核准備好數據,在內核准備數據的過程中,當前線程是阻塞的,這樣就會導致如果某個線程因為讀取IO的時間過長(比如讀取文件、寫文件),則它勢必會影響其他線程的執行。如果對 同步IO、 異步IO 不了解的同學,可以看如下兩篇文章:

既然 同步IO有缺陷,那我們是不是可以調整為 異步IO呢?完全可以,這就是 Proactor 模式

什么是 Proactor 模式

Proactor 模式整體與Reactor 模式一致,區別就在於Proactor模式將所有I/O操作都交給主線程和內核來處理,工作線程僅僅負責業務邏輯。模型如下:

  • Procator Initiator:負責創建Handler和Procator,並將Procator和Handler都通過Asynchronous operation processor注冊到內核。

  • Handler:執行業務流程的業務處理器。

  • Asynchronous operation processor:負責處理注冊請求,並完成IO操作。完成IO操作后會通知Procator。

  • Procator:根據不同的事件類型回調不同的handler進行業務處理。

這里需要注意的是: Proactor關注的不是就緒事件,而是完成事件,這是區分Reactor模式的關鍵點

然而可惜的是,Linux下的異步 I/O 是不完善的,aio 系列函數是由 POSIX 定義的異步操作接口,不是真正的操作系統級別支持的,而是在用戶空間模擬出來的異步,並且僅僅支持基於本地文件的 aio 異步操作,網絡編程中的 socket 是不支持的,這也使得基於 Linux 的高性能網絡程序都是使用 Reactor 方案。

而 Windows 里實現了一套完整的支持 socket 的異步編程接口,這套接口就是 IOCP,是由操作系統級別實現的異步 I/O,真正意義上異步 I/O,因此在 Windows 里實現高性能網絡程序可以使用效率更高的 Proactor 方案。

優缺點

  • 優點

    • 性能確實是強大,效率也高
  • 缺點

    • 復雜。性能好,效率高,東西是好東西,但是使用起來就是復雜。

    • 操作系統支持。上面提到過,Linux系統對異步IO支持不是很好,不是很完善

Proactor 模式與Reactor 模式

Proactor模式與Reactor模式 的區別有如下幾點:

  • Reactor 模式注冊的是文件描述符的就緒事件。當Reactor 模式有事件發生時,它需要判斷當前事件是讀事件還是寫事件,然后在調用系統的read或者write將數據從內核中拷貝到用戶數據區,然后進行業務處理。

  • Proactor模式注冊的則是完成事件。即發起異步操作后,操作系統將在內核態完成I/O並拷貝數據到用戶提供的緩沖區中,完成后通知Proactor進行回調,用戶只需要處理后續的業務即可。

  • Reactor模式實現同步I/O多路分發

  • Proactor模式實現異步I/O分發

在 Linux 操作系統下實現高並發網絡編程依然以Reactor 模式為主。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM