文章目錄
- 前言
- 阻塞與非阻塞
- 同步與異步
- 復雜的網絡IO
- 真正的異步IO
- IO分類與示例
- 總結
前言
這幾個名詞在程序開發時經常聽到,但是突然問起來各個詞的含義一時間還真是說不清楚,貌似這幾個詞都是翻譯過來的,每個人的解釋都不太一樣,我對這幾個詞的理解也不是一成不變的,隨著開發經驗的積累,漸漸有了自己的記憶方式,所以總結一下,不一定準確,有問題可以一起聊一聊。
先說說我的結論:阻塞與非阻塞是指等待執行結果時的狀態,同步與異步是指獲取執行結果的方式,讀起來有點繞口,聽起來也迷迷糊糊的,沒關系,我們用具體的例子來說明應該就容易理解了。
阻塞與非阻塞
先說說『阻塞與非阻塞是指等待執行結果時的狀態』這一句,是說在執行某個操作或者某個函數時,在沒有拿到我們想要的結果時,我們的狀態是怎樣的,如果是一直等就是【阻塞】的,如果發現沒有結果就去做別的事情了就是【非阻塞】的。
以常見的網絡IO為例,服務器對客戶端連接的socket調用read
函數,試圖獲取客戶端發送的請求數據,但是客戶端并不總是有數據發送過來,所以想要獲得數據我可以采用【阻塞】方式一直等,也可以采用【非阻塞】方式,在發現此時沒有數據時就先去干別的事,一會再來看看。
同步與異步
再來說說『同步與異步是指獲取執行結果的方式』這一句,以游戲中的常見升級發獎為例,可以主動調用升級函數,在執行完成后返回升級的結果,然后根據結果來發獎勵,也就是【同步】寫法,也可以注冊一個監聽等級變化的回調函數,注冊完我就不管了,當升級時會將升級的結果通過回調函數傳回來,這就是【異步】處理方式。
復雜的網絡IO
為什么同步和異步沒有用網絡IO來舉例呢?因為網絡IO這里的情況更加復雜,雖然你注冊了回調函數,但它很可能是個同步IO,究竟怎么回事,一起來看看。
我們知道要想從IO讀取數據,需要經歷「內核數據準備好」和「數據從內核態拷貝到用戶態」兩個過程,還是以read
函數為例,如果設置為阻塞模式,相當于read
函數等待了「內核數據準備好」和「數據從內核態拷貝到用戶態」兩個過程,然后取到IO數據,如果設置成非阻塞模式,當內核數據沒準備好會直接返回,也就是不會等待第一個過程,但是當數據準備好時,會直接等待第二個過程完成后,將結果數據返回。
所以無論是否阻塞,我們都等待了第二個階段,等著它執行完成后獲取結果,所以這兩種都是同步IO。
那作為IO多路復用里的“一哥”epoll也是同步IO嗎?是的!那封裝了select/poll/epoll的libevent可是用了Reactor模式,支持事件回調,它也是同步IO嗎?是的!
真正的異步IO
有點驚呆了不是嗎?那究竟什么是異步IO呢?還真有!Windows 里實現了一套完整的支持 socket 的異步編程接口 IOCP
,而 Linux 是在 2019 年 5.1 版本 內核首次引入的高性能異步I/O 框架 io_uring
,我確實都沒用過,感興趣的可以試一下
是否是異步IO就看「數據從內核態拷貝到用戶態」這個過程需不需要等待,如果需要邏輯層自己等待這個過程取數據就是同步IO,如果這個過程都不用等,調用回調函數時已經把內核態的數據拷貝出來,并且通過回調將數據進行了回傳,這就是異步IO。
IO分類與示例
所以總結下來一共有這么幾種:同步阻塞IO,同步非阻塞IO,異步IO,為啥不區分異步阻塞IO和異步非阻塞IO呢?你在阻塞時搞個異步試試,辦不到吧,所以異步只能與非阻塞搭配,也就習慣只寫異步IO了。
一頓理論講下來可能還是比較抽象,那我們再舉個日常生活中的例子,比如中午買飯的過程:
同步阻塞IO就好像,你去食堂吃面條,但是你去這一鍋面條還沒煮好,然后你就一直在那里等啊等,等了一段時間終于做好了(數據準備的過程),但是你還得繼續等工作人員把面條(內核空間)打到你的餐盤里(用戶空間),才能找個桌子開始吃飯。
同步非阻塞IO就好像,你又去食堂吃飯,問大叔飯做好了沒有,告訴你沒有你就離開了,過了一會,你又來飯堂問大叔飯做好了嗎,人家說說做好了,于是你等著把飯打到你的餐盤里,后面這個過程你是得等待的。
異步IO就好像,你在十分焦急的寫BUG,這時到飯點肚子餓了,給食堂大叔打電話,等飯做好了麻煩給我送一份,等到飯好了真的送來直接就能吃了,一直在抓緊寫BUG中間沒有等待(做夢中)
我想大部分同學吃午飯都是第一種同步阻塞IO吧,第二種同步非阻塞IO可能也有,但是不是要重新排隊啊,如果是第三種異步IO的情況,我只能說大哥/姐,我跟你混了~~
總結
- IO分為同步阻塞IO,同步非阻塞IO,異步IO三類
- 異步IO有Windows平臺的
IOCP
和 Linux 平臺的io_uring
- 從IO讀取數據,需要經歷「內核數據準備好」和「數據從內核態拷貝到用戶態」兩個過程
- 分析阻塞和非阻塞看是否等待第一個過程,分析同步與異步看是否等待第二個過程
人生的岔路口,不知是機會還是風險,邊走邊看吧,畢竟路還是在腳下,空想也到不了終點~