同步阻塞IO,同步非阻塞IO,異步IO,IO多路復用

同步與異步,阻塞與非阻塞,以及這四個名詞之間的兩兩集合,是學習并發編程/網絡編程時會遇到的幾個重要概念

注:以下IO指的是linux下的I/O

同步與異步:

同步與異步這兩個概念,可以從消息的通信機制上來理解

當一個進程需要執行I/O操作時,如果進程需要一直等待操作結果的返回,甚至被掛起,那么這就屬于同步的范疇

如果在等待I/O結果返回的過程中,進程可以執行其他代碼,那么這就屬于異步

比如我要分析一個大小為10G的日志文件,在讀取日志文件內容的時候會耗費較長一段時間

如果采用同步操作,那么相關進程會一直等待文件讀取完畢,這段時間內CPU會一直處于等待狀態

如果采用異步操作,相關進程可以把讀取I/O的指令傳送給內核,在內核操作I/O的過程中,相關進程可以執行其他代碼,比如初始化一些變量,或者一些構造函數,甚至進行其他高計算量的任務

異步的執行效率并不是永遠比同步高,因為進程(內核態到用戶態)的切換也需要消耗一定的計算資源

所以異步更適合于進程切換需要少,I/O操作時間長的任務.Linux下常用的select/epoll/poll函數就是采用同步模型

阻塞與非阻塞

要注意的一點是,如果一份任務采用異步模型,那么它肯定是非阻塞的,同步模型才需要討論阻塞與非阻塞

如果等待I/O的過程中,進程掛起,直到內核返回信息說I/O執行完畢,進程才繼續執行接下來的代碼,那么就屬于阻塞

如果在等待I/O過程中,進程沒有掛起,可以執行其他操作,但是每隔一段時間得主動去詢問內核I/O執行完畢沒有,那么就屬于非阻塞

同步非阻塞與異步很相像,區別就在于當前進程需不需要去向內核詢問I/O執行完畢了沒有

I/O多路復用

由于linux下多數I/O都屬于同步模型,如果遇到某個I/O執行時間過長時,會導致整個進程都被阻塞住.
(這里有一點需要注意,即便是同步非阻塞模型,在I/O執行完畢拷貝到內存的過程當中,也是屬于阻塞的)
為了解決這個問題,人們又提出了I/O多路復用技術,將I/O操作分離開(可以是多個I/O),利用一個線程做輪詢操作,當哪個I/O操作執行完畢可以進行接下來的操作,就他通知相關的輪詢函數,再由輪詢函數執行接下來的操作,這就是I/O多路復用.

結尾

上面的內容只是很表面得介紹這幾個概念,更適合入門理解
如果想學到更多關于這些概念的知識,可以參考一些權威書籍
另外很推薦這篇文章:
IO - 同步,異步,阻塞,非阻塞 (亡羊補牢篇)
以及知乎這個回答:
怎樣理解阻塞非阻塞與同步異步的區別?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容