五種Linux IO模型+同步異步,阻塞非阻塞,再也不怕頭條面試官掛我了

背景

小K在面試中被頭條面試官問了五種IO模型,只是含糊的回答了;頭條面試官一臉不滿意的回答,你回去花兩小時認真看看吧,保證你有收穫,最後,當然就是面試不通過了,所以在面試中,IO模型是非常常見的問題,我們需要理解IO模型的分類,特點,爲什麼有這種模型。

首先記住從245原則去講解,2代表兩類;第一類有4個名詞,代表阻塞,非阻塞,同步,異步;第二類有5個名詞,代表阻塞IO,非阻塞IO,IO多路複用,信號驅動IO,異步IO

第一類

瞭解第一類之前,我們需要先了解一個IO操作做了什麼事情,對於熟悉第一類的大佬,可以跳過第一類,去了解第二類IO模型

linux系統分爲用戶態和內核態,發起一個IO操作的過程分類兩步:

  1. 用戶態的線程發起IO操作,那就要內核準備好數據

  2. 內核態準備好數據後,用戶態喚醒,把數據從內核拷貝到用戶的線程緩衝區

1. 阻塞

容易記的關鍵詞:線程停了;阻塞的意思就是用戶的線程發起一個IO操作,線程就停止了,直到等待內核準備好數據,線程才能繼續運行

2. 非阻塞

容易記的關鍵詞:線程還能動;非阻塞的意思就是用戶的線程發起一個IO操作,線程沒有停止,還可以繼續做其他事情,也就是說線程通知內核IO操作後,繼續去做其他事情了

3. 同步

容易記的關鍵詞:直到整個操作完成;同步的意思可以理解爲做一件事件,必須等到了結果,才能繼續做其他事情,那麼對於IO操作,線程是需要做完了第一步等操作和第二部數據拷貝的操作,才能繼續做其他的事情

4. 異步

容易記的關鍵詞:不需要整個操作完成;異步的意思可以理解爲做一件事情,通知開始做後,便可以做其他事情了,系統會幫我們做完剩下的事情,那麼對於IO操作,線程只需要通知IO操作開始,就可以做其他操作了,最後內核會幫我們做完兩件事情,等數據準備和數據拷貝

第二類

現在便來介紹IO模型了,每個IO模型都有其特點,不斷進化

1. 阻塞IO

看到阻塞IO,大家應該有印象了吧,那就是關鍵字:線程停了

應用的進程調用IO操作後,一直等到內核準備好數據,然後將數據從內核複製到用戶的進程緩衝區,最後才能進行其他操作

 

場景描述:

小K需要跑一個程序,第一步需要編譯,編譯完成後,第二步再運行程序;阻塞IO場景就是小k編譯程序後,一直盯着編譯過程,等到編譯完成後,就立刻運行編譯好的程序;這樣是不是不能做其他事情了,而且運行程序也無延遲

優點:

  1. 不消耗CPU,發起IO後,進程就阻塞了,所以不消耗CPU

  1. 能夠及時返回數據,無延遲

缺點:

  1. 進程不能進行其他操作,因爲等待數據和準備好數據是需要時間的,如果能夠不阻塞,那便可以進行其他的IO發起操作等

  2. 性能較低

2. 非阻塞IO

針對阻塞IO,是不是可以優化一下,在阻塞的時候,去做一下其他事情,然後在看數據有沒有準備好;所以整個操作可以看作,發起IO操作後,不進行阻塞,而是不斷主動去輪詢內核,看數據是不是準備好了,數據準備好後,就可以進行拷貝了

 

場景描述:

小K編譯程序的時候,去寫一下代碼,然後回來看編譯過程,重複這個過程,直到程序編譯好,然後再運行程序

優點:

在等待任務完成的時候,還可以去做其他事情,提高CPU使用率

缺點:

  1. 任務存在延遲,因爲定時輪詢,可能輪詢不及時

  2. 消耗CPU,因爲定時去輪詢時,進程不是阻塞態,是運行狀態,所以是消耗CPU的,如果多個進程都定時輪詢,CPU消耗是很大的

3. IO 多路複用

針對與非阻塞IO,多個進程都進行輪詢的話,系統需要進程資源,也消耗CPU,所以支撐不了很多的IO操作,這樣便出現了IO多路複用;我們可以把多個IO操作註冊到IO複用的函數(select,poll,epoll)中,這樣便可以由一個系統調用去監聽多個IO,等到有一個或多個IO操作的數據就緒後,系統調用就會立刻去通知用戶態,用戶再進行該就緒IO的數據拷貝操作

 

場景描述:

小K一下需要編譯10個程序,如果每個定時去看,得查看10次,很麻煩;聰明的小K便寫了一個腳本,需要編譯一個程序,就往腳本配置文件註冊該編譯程序的信息;腳本運行時,如果發現有編譯完成的程序,立刻告訴小K,美滋滋,可以運行該程序了,運行完程序後,又盯着腳本看,如果再有編譯好的程序,再運行。。。

優點:

  1. 支持高數量的IO操作,適用於高併發的場景

  2. 系統開銷小,一個進程做多個IO操作

缺點:

  1. 該模型還是同步模型,整個操作(等待數據和拷貝數據)都需要用戶進程去完成

  2. 在IO沒有就緒的情況下,會阻塞進程

4. 信號驅動IO

在IO多路複用中,優點還是挺多的了,但是針對缺點1阻塞,和更好的針對網路協議,便有了信號驅動IO;信號驅動IO會安裝好信號處理函數(可以理解爲數據拷貝),進程發起信號驅動IO時,就立刻收到返回,便可以做其他事情了,等內核準備好數據時,便通知信號處理函數,信號處理函數便進行數據拷貝的操作

但是信號驅動IO適用於UDP協議,而不適用於TCP協議,因爲UDP收到數據包時,纔會產生信號,而TCP不同,三次握手,四次揮手,心跳檢查等等,都會產生信號,這樣信號程序是無法判斷是否是數據包的(如有錯誤,請各位大佬提醒)

 

場景描述:

聰明的小K在編譯腳本的基礎上加了彈框功能彈框功能,如果有就緒情況,就立刻彈框,小K便可以知道編譯完成了,去運行程序

優點:

  1. 非阻塞模型,進程發起調用後,立刻返回,便可以進行其他操作了

缺點:

  1. 在數據拷貝的時候,還是需要用戶態去主動去操作

異步非阻塞IO

這個就是真正強大的IO,用戶發起IO操作後,就不用管了,去做其他事情,內核會準備好數據,並把數據拷貝到用戶的進程中

 

場景描述

小K現在把編譯腳本加上了運行腳本,只要發起腳本,就可以去寫其他代碼了,腳本會自動完成編譯+運行操作

優點:

  1. 非阻塞,發起IO操作後,還可以做其他事情

  2. 異步,整個IO操作,只需要發起操作,而不需要進行等待數據完成和數據拷貝操作,這些內核都做好了

缺點:

  1. 優點系統不支持

PS

請大家多多關注小K和微信公衆號,有好文章多多分享哦

 

 

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