同步異步阻塞非阻塞

阻塞I/O:套接字在調用接口時,會一直處於等待狀態,直到內核將數據準備好返給套接字,如下圖:

  e83d68da03da2e8c1568b4b4b630edfd_b.jpg

非阻塞I/O:套接字在調用接口時,每請求一次數據,內核根據是否準備好數據都會返回給套接字信息,如果內核沒準備好,返回一個錯誤狀態碼,準備好返回數據,這樣會消耗大量的cpu,如下圖:


4bc31cab27a9a732ab7d1ba9e674ed64_b.jpg

I/O複用:I/O複用方式主要包含select、poll、epoll,他們作爲代理來處理I/O請求,I/O複用是阻塞和非阻塞的綜合,可以處理多個請求,所有的請求都要經過代理,代理判斷內核是否準備好數據,內核準備好數據後會通知代理,(select和poll在接受到內核的通知後會將所有請求輪詢,確定是哪一個請求的數據準備好了,然後返回給數據,沒有準備好數據的請求,依然阻塞在select和poll內;epoll是升級版的代理,內核準備好數據後,通知epoll,epoll只是輪詢準備好的數據,直接將數據發送給響應的請求,其他沒準備好的請求依然阻塞)如下圖:

o_untitled3.png


異步I/O:這類函數的工作機制是告知內核啓動某個操作,並讓內核在整個操作(包括將數據從內核拷貝到用戶空間)完成後通知我們,如下圖:

o_untitled5.png



對unix來講:阻塞式I/O(默認),非阻塞式I/O(nonblock),I/O複用(select/poll/epoll)都屬於同步I/O,因爲它們在數據由內核空間複製回進程緩衝區時都是阻塞的(不能幹別的事)。只有異步I/O模型(AIO)是符合異步I/O操作的含義的,即在1數據準備完成、2由內核空間拷貝回緩衝區後 通知進程,在等待通知的這段時間裏可以幹別的事


例如:

  1. 我去買一本書,立即買到了,或者沒有就走了,這就是非阻塞;(編程中設置IO成非阻塞,返回後再去檢查描述符,或者等待通知,然後再去讀取。相當於老闆告訴我可以先忙點別的,過一會再來問問,或者老闆通知我。但期間這個窗口(文件描述符)別人是用不了的)("立即買到了"在IO中也需要等待,不能算非阻塞IO)

  2. 如果恰好書店沒有,我就等一直等到書店有了這本書買到了才走,這就是阻塞;而排在我後面的人呢只有我買到了書後才能再買書了。

  3. 如果書店恰好沒有,我就告訴書店老闆,書來了告訴我一聲讓我來取或者直接送到我家,然後我就走了,去做別的事了,這就是異步。這時候如果很多人來買書,都是老闆登記一下完事。 (從IO角度來說,“告訴我來取”,這個近似於信號驅動IO,不能算異步IO。必須書送到我家纔算是異步,如果不送到我家,我想看這本書之前,終究還是需要我跑一趟)

  4. 前面兩種情況,非阻塞和阻塞都可以稱爲同步。

反映在編程方面就是 用戶進程 調用 系統調用。(用戶進程對應我,內核 對應 書店老闆,書對應數據資源data , 買書就是一個系統調用了,其中內核拷貝數據到進程這個過程近似於老闆送書到我手中)。



作者:Shihui wang
鏈接:https://www.zhihu.com/question/19732473/answer/14413599
來源:知乎
著作權歸作者所有,轉載請聯繫作者獲得授權。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章