[轉載]使用非同步 I/O 大大提高應用程式的效能
使用非同步 I/O 大大提高應用程式的效能
學習何時以及如何使用 POSIX AIO API
http://www.ibm.com/developerworks/cn/linux/l-async/
級別: 中級
M. Tim Jones (mtj@mtjones.com), 顧問工程師, Emulex
2006 年 9 月 28 日
Linux® 中最常用的輸入/輸出(I/O)模型是同步 I/O。在這個模型中,當請求發出之後,應用程式就會阻塞,直到請求滿足為止。這是很好的一種解決方案,因為呼叫應用程式在等待 I/O 請求完成時不需要使用任何中央處理單元(CPU)。但是在某些情況中,I/O 請求可能需要與其他程式產生交疊。可移植作業系統介面(POSIX)非同步 I/O(AIO)應用程式介面(API)就提供了這種功能。在本文中,我們將對這個 API 概要進行介紹,並來了解一下如何使用它。
AIO 簡介
Linux 非同步 I/O 是 Linux 核心中提供的一個相當新的增強。它是 2.6 版本核心的一個標準特性,但是我們在 2.4 版本核心的補丁中也可以找到它。AIO 背後的基本思想是允許程式發起很多 I/O 操作,而不用阻塞或等待任何操作完成。稍後或在接收到 I/O 操作完成的通知時,程式就可以檢索 I/O 操作的結果。
I/O 模型
在深入介紹 AIO API 之前,讓我們先來探索一下 Linux 上可以使用的不同 I/O 模型。這並不是一個詳盡的介紹,但是我們將試圖介紹最常用的一些模型來解釋它們與非同步 I/O 之間的區別。圖 1 給出了同步和非同步模型,以及阻塞和非阻塞的模型。
圖 1. 基本 Linux I/O 模型的簡單矩陣
每個 I/O 模型都有自己的使用模式,它們對於特定的應用程式都有自己的優點。本節將簡要對其一一進行介紹。
同步阻塞 I/O
|
|
最常用的一個模型是同步阻塞 I/O 模型。在這個模型中,使用者空間的應用程式執行一個系統呼叫,這會導致應用程式阻塞。這意味著應用程式會一直阻塞,直到系統呼叫完成為止(資料傳輸完成或發生錯誤)。呼叫應用程式處於一種不再消費 CPU 而只是簡單等待響應的狀態,因此從處理的角度來看,這是非常有效的。
圖 2 給出了傳統的阻塞 I/O 模型,這也是目前應用程式中最為常用的一種模型。其行為非常容易理解,其用法對於典型的應用程式來說都非常有效。在呼叫 read 系統呼叫時,應用程式會阻塞並對核心進行上下文切換。然後會觸發讀操作,當響應返回時(從我們正在從中讀取的裝置中返回),資料就被移動到使用者空間的緩衝區中。然後應用程式就會解除阻塞(read 呼叫返回)。
圖 2. 同步阻塞 I/O 模型的典型流程
從應用程式的角度來說,read 呼叫會延續很長時間。實際上,在核心執行讀操作和其他工作時,應用程式的確會被阻塞。
同步非阻塞 I/O
同步阻塞 I/O 的一種效率稍低的變種是同步非阻塞 I/O。在這種模型中,裝置是以非阻塞的形式開啟的。這意味著 I/O 操作不會立即完成,read 操作可能會返回一個錯誤程式碼,說明這個命令不能立即滿足(EAGAIN 或 EWOULDBLOCK),如圖 3 所示。
圖 3. 同步非阻塞 I/O 模型的典型流程
非阻塞的實現是 I/O 命令可能並不會立即滿足,需要應用程式呼叫許多次來等待操作完成。這可能效率不高,因為在很多情況下,當核心執行這個命令時,應用程式必須要進行忙碌等待,直到資料可用為止,或者試圖執行其他工作。正如圖 3 所示的一樣,這個方法可以引入 I/O 操作的延時,因為資料在核心中變為可用到使用者呼叫 read 返回資料之間存在一定的間隔,這會導致整體資料吞吐量的降低。
非同步阻塞 I/O
另外一個阻塞解決方案是帶有阻塞通知的非阻塞 I/O。在這種模型中,配置的是非阻塞 I/O,然後使用阻塞 select 系統呼叫來確定一個 I/O 描述符何時有操作。使 select 呼叫非常有趣的是它可以用來為多個描述符提供通知,而不僅僅為一個描述符提供通知。對於每個提示符來說,我們可以請求這個描述符可以寫資料、有讀資料可用以及是否發生錯誤的通知。
圖 4. 非同步阻塞 I/O 模型的典型流程 (select)
select 呼叫的主要問題是它的效率不是非常高。儘管這是非同步通知使用的一種方便模型,但是對於高效能的 I/O 操作來說不建議使用。
非同步非阻塞 I/O(AIO)
最後,非同步非阻塞 I/O 模型是一種處理與 I/O 重疊進行的模型。讀請求會立即返回,說明 read 請求已經成功發起了。在後臺完成讀操作時,應用程式然後會執行其他處理操作。當 read 的響應到達時,就會產生一個訊號或執行一個基於執行緒的回撥函式來完成這次 I/O 處理過程。
圖 5. 非同步非阻塞 I/O 模型的典型流程
在一個程式中為了執行多個 I/O 請求而對計算操作和 I/O 處理進行重疊處理的能力利用了處理速度與 I/O 速度之間的差異。當一個或多個 I/O 請求掛起時,CPU 可以執行其他任務;或者更為常見的是,在發起其他 I/O 的同時對已經完成的 I/O 進行操作。
下一節將深入介紹這種模型,探索這種模型使用的 API,然後展示幾個命令。
非同步 I/O 的動機
從前面 I/O 模型的分類中,我們可以看出 AIO 的動機。這種阻塞模型需要在 I/O 操作開始時阻塞應用程式。這意味著不可能同時重疊進行處理和 I/O 操作。同步非阻塞模型允許處理和 I/O 操作重疊進行,但是這需要應用程式根據重現的規則來檢查 I/O 操作的狀態。這樣就剩下非同步非阻塞 I/O 了,它允許處理和 I/O 操作重疊進行,包括 I/O 操作完成的通知。
除了需要阻塞之外,
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/81/viewspace-250397/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- socket阻塞與非阻塞,同步與非同步、I/O模型非同步模型
- 談談對不同I/O模型的理解 (阻塞/非阻塞IO,同步/非同步IO)模型非同步
- 使用非同步元件優化Vue應用程式的效能非同步元件優化Vue
- 使用Task實現非阻塞式的I/O操作
- NodeJs 非同步 I/ONodeJS非同步
- python 非同步 I/OPython非同步
- Java 非同步 I/OJava非同步
- 玩轉 PHP 網路程式設計全套之 I/O 複用PHP程式設計
- Google I/O 2018 : 應用於 PC 端的 PWAGo
- 網路程式設計-I/O複用程式設計
- 如何監測 Linux 的磁碟 I/O 效能Linux
- 一篇文章幫你徹底搞清楚“I/O多路複用”和“非同步I/O”的前世今生非同步
- Linux下的5種I/O模型與3組I/O複用Linux模型
- Java非阻塞I/O模型之NIO說明Java模型
- 如何使用ABAP非同步RFC呼叫提升應用效能非同步
- 簡述python非同步i/o庫 —— asyncioPython非同步
- 從同步原語看非阻塞同步以及Java中的應用Java
- 【面試】I/O 複用面試
- 使用phpAnalysis打造PHP應用非侵入式效能分析器PHP
- 程式設計競賽中 C/C++ I/O 的使用程式設計C++
- Java中I/O流:阻塞和非阻塞範例Java
- 深入理解 python 非同步 i/o 庫 —— asyncioPython非同步
- 2.3.6 應用程式同步
- 使用 iotop 監控哪些程式在進行I/O操作
- I/O已經不再是效能瓶頸
- 計算機I/O與I/O模型計算機模型
- 2.3.6.1 單個應用程式的同步
- 一起看 I/O | 用 Health Connect 連通應用間的健康資料
- 【Linux網路程式設計】I/O 多路複用技術Linux程式設計
- 從網路I/O模型到Netty,先深入瞭解下I/O多路複用模型Netty
- 服務端 I/O 效能:Node、PHP、Java、Go 的對比服務端PHPJavaGo
- I/O多路複用技術(multiplexing)
- 用bonnie++測試磁碟I/O
- 系統程式設計 - I/O模型程式設計模型
- Hadoop的I/O操作Hadoop
- 同步阻塞、同步非阻塞、多路複用的介紹
- I/O流
- Java I/OJava
- node.js的非同步I/O、事件驅動、單執行緒Node.js非同步事件執行緒