區分

一個輸入操作通常包括兩個階段:

  • 等待數據準備好
  • 從內核向進程複製數據

對於一個套接字上的輸入操作,第一步通常涉及等待網路數據從網路到達。當所等待數據到達後,它被複制到內核中的某個緩衝區。第二部就是把數據從內核緩衝區複製到應用進程緩衝區。

同步IO和非同步IO的區別就在於第二個步驟是否阻塞,如果實際的IO讀寫阻塞請求過程,那麼就是同步IO,因此阻塞IO、非阻塞IO、IO復用、信號驅動IO都是同步IO,如果不阻塞,而是操作系統幫你做完IO操作再將結果返回給你,那麼就是非同步IO。

阻塞IO和非阻塞IO的區別在第一步,發起IO請求是否會被阻塞,如果阻塞直到完成那麼就是傳統的阻塞IO,如果不阻塞,那麼就是非阻塞IO。

阻塞式IO

應用進程被阻塞,知道數據複製到應用進程緩衝區才返回。

應該注意到,在阻塞過程中,其他程序還可以執行,因此阻塞並不意味著整個操作系統被阻塞。因為其他程序還可以運行,因此不消耗CPU時間,這種模型的CPU利用率會比較高。

非阻塞IO

應用程序執行系統調用之後,內核返回一個錯誤碼。應用程序還可以繼續運行,但是需要不斷的執行系統調用來獲知IO是否完成,這種方式成為輪詢。

由於CPU要處理更多的系統調用,因此這種模型的CPU利用率比較低。

IO復用

使用select或者poll等待數據,並且可以等待多個套接字中的任何一個變為可讀。這一過程會被阻塞,當某一個套接字可讀時返回,之後使用recvfrom把數據從內核複製到進程中。

它可以讓但個進程具有處理多個I/O事件的能力,又被稱為Event Driven IO,即事件驅動IO。

信號驅動IO

應用進程使用sigaction系統調用,內核立即被返回,應用進程可以繼續執行,也就是說等待數據階段應用程序時非阻塞的。內核在數據到達時嚮應用進程發送SIGIO信號,應用進程收到之後在信號處理程序中調用recvfrom將數據從內核中複製到應用進程。

相比於非阻塞IO的輪詢方式,信號驅動I/O的CPU利用率更高。

非同步IO

應用進程執行aio_read系統調用會立即返回,應用進程可以繼續執行,不會被阻塞,內核會在所有操作完成之後嚮應用進程發送信號。

非同步IO與信號驅動IO的區別在於,非同步IO的信號是通知應用進程IO完成,而驅動IO的信號是通知應用程序可以開始IO。

參考:

  • cs-notes-socket

推薦閱讀:

相關文章