首先來看看Reactor模式,Reactor模式應用于同步I/O的場景。我們以讀操作為例來看看Reactor中的具體步驟:
讀取操作:
1. 應用程式注冊讀就需事件和相關聯的事件處理器
2. 事件分離器等待事件的發生
3. 當發生讀就需事件的時候,事件分離器調用第一步注冊的事件處理器
4. 事件處理器首先執行實際的讀取操作,然後根據讀取到的内容進行進一步的處理
下面我們來看看Proactor模式中讀取操作和寫入操作的過程:
1. 應用程式初始化一個異步讀取操作,然後注冊相應的事件處理器,此時事件處理器不關注讀取就緒事件,而是關注讀取完成事件,這是差別于Reactor的關鍵。
2. 事件分離器等待讀取操作完成事件
3. 在事件分離器等待讀取操作完成的時候,作業系統調用核心線程完成讀取操作,并将讀取的内容放入使用者傳遞過來的緩存區中。這也是差別于Reactor的一點,Proactor中,應用程式需要傳遞緩存區。
4. 事件分離器捕獲到讀取完成事件後,激活應用程式注冊的事件處理器,事件處理器直接從緩存區讀取資料,而不需要進行實際的讀取操作。
Proactor中寫入操作和讀取操作,隻不過感興趣的事件是寫入完成事件。
從上面可以看出,Reactor和Proactor模式的主要差別就是真正的讀取和寫入操作是有誰來完成的,Reactor中需要應用程式自己讀取或者寫入資料,而Proactor模式中,應用程式不需要進行實際的讀寫過程,它隻需要從緩存區讀取或者寫入即可,作業系統會讀取緩存區或者寫入緩存區到真正的IO裝置.
綜上所述,同步和異步是相對于應用和核心的互動方式而言的,同步 需要主動去詢問,而異步的時候核心在IO事件發生的時候通知應用程式,而阻塞和非阻塞僅僅是系統在調用系統調用的時候函數的實作方式而已。
參考資料:
http://blog.csdn.net/caiwenfeng_for_23/article/details/8458299
https://segmentfault.com/q/1010000002795782