組塞式,非阻塞式,同步非同步
請求描述: `阻塞/非阻塞` 和 `同步/非同步` 不是一個概念。舉幾個簡單的例子。 當程序呼叫一個進行IO操作的API時(比如read函式),在資料沒有到達前,read 會掛起,程序會卡住。在資料讀取完畢返回給程序時, read 返回(返回值為讀取到的位元組數,資料從核心拷貝到使用者空間),然後程序繼續執行。那麼這次 read 呼叫,是阻塞的。 非阻塞就是 read 在資料沒有讀取完畢前,就返回了(返回值為-1,errno 設定為 EAGAIN)。此時程序沒有拿到需要的資料。那怎麼辦?
有兩種辦法。
一種是同步: 因為程序沒辦法知道資料什麼時候才真正讀取完畢了,所以需要每隔一段時間就去輪詢一下(就是重新呼叫 read,看是不是資料真的已經讀取完畢了)。 大部分場景中都不會使用這種方式。但在某些特殊的情況下效率會特別高。一種是非同步: 早期的非同步實現方式是核心給程序發訊號(SIGIO 或者 SIGPOLL)。資料讀寫完畢後,核心發訊號給程序,然後程序內的訊號處理函式再呼叫 read 讀取資料(這時可以確保資料真的已經讀取完畢了)。但這種方式有一個小小的瑕疵,就是在程序進行多個 fd 讀寫的時候,訊號來的時候沒辦法分清到底是哪個 fd 上的資料已經真正準備好了。所以程序還是要對所有持有的 fd 進行 read 呼叫。 後來的非同步實現,就有了更好的 select / poll / epoll(I/O multiplexing)。現在基本上像比較流行的 Nginx / Redis 都用 epoll(在 FreeBSD 上是 kqueue) --------------------- 作者:樂楊俊 來源:CSDN 原文:https://blog.csdn.net/leyangjun/article/details/62236241 版權宣告:本文為博主原創文章,轉載請附上博文連結!
小樂愛喝茶,廢話不說,煮開水。
出場人物:小樂,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。
1 小樂把水壺放到火上,立等水開。(同步阻塞)
—— 小樂覺得自己有點傻
2 小樂把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞)
—— 小樂還是覺得自己有點傻,於是變高端了,買了把會響笛的那種水壺。水開之後,能大聲發出嗚嗚~~~~的噪音。
3 小樂把響水壺放到火上,立等水開。(非同步阻塞)
—— 小樂覺得這樣傻等意義不大
4 小樂把響水壺放到火上,去客廳看電視,水壺響之前不再去看它了,響了再去拿壺。(非同步非阻塞)
—— 小樂覺得自己聰明瞭。
所謂同步非同步,只是對於水壺而言。 普通水壺,同步;響水壺,非同步。 雖然都能幹活,但響水壺可以在自己完工之後,提示小樂水開了。這是普通水壺所不能及的。
同步只能讓呼叫者去輪詢自己(情況2中),造成小樂效率的低下。
所謂阻塞非阻塞,僅僅對於小樂而言。
—— 立等的小樂,阻塞;看電視的小樂,非阻塞。
情況1和情況3中小樂就是阻塞的,媳婦喊他都不知道。
雖然3中響水壺是非同步的,可對於立等的小樂沒有太大的意義。
所以一般非同步是配合非阻塞使用的,這樣才能發揮非同步的效用。