一頓飯的事兒,搞懂Linux5種IO模型

帶你聊技術發表於2023-05-06

來源:三分惡

人生有三大難題,事業、愛情,和——這頓吃什麼!

人在家中躺,肚子餓得響,又到了不得不吃的時候,這頓飯該怎麼吃?吃什麼呢?

Linux裡有五種IO模型:阻塞IO非阻塞IO多路複用IO訊號驅動式IO非同步IO,我發現這五種IO模型,其實能和吃飯這件事關聯起來。

阻塞IO(Blocking I/O)

阻塞IO是最常見的IO模型。

當發起一個IO操作時,比如讀取資料,系統會呼叫read()函式。如果請求的資料沒有準備好,此時程式會被掛起(blocked),進入等待狀態。直到資料準備好,而且複製到應用程式的緩衝區,這時候才會返回。

從呼叫到返回,整個時間段都是阻塞的,所以被稱為阻塞IO。

一頓飯的事兒,搞懂Linux5種IO模型

就像是手機沒電的時候,去飯館吃飯,我點完菜,只能等著廚師做好,服務員端上來,我才能愉快乾飯。這段時間,我就只能坐在座位上乾等。

非阻塞IO(Non-Blocking I/O)

阻塞IO,還是比較浪費資源的,那麼非阻塞IO就來了。

所謂非阻塞IO,是在呼叫IO操作時,如果緩衝區沒有資料的話,直接返回一個錯誤碼。應用程式需要不斷輪詢,來檢查資料是否準備好。資料準備好了,就返回資料。

一頓飯的事兒,搞懂Linux5種IO模型

就像是我奢侈一把,想吃個西餐,於是就去了肯德基,點完餐,我就可以坐著刷刷手機。當然,我還需要時不時地看看我的餐是不是已經備好,餐備好了,就去取一下。

多路複用IO(I/O Multiplexing)

雖然非阻塞IO相比阻塞IO,效能提升了很多,但是輪詢過程中,還是有大量的系統呼叫,上下文切換的開銷比較大。

那麼,多路複用IO就來了。

多路指的是多個資料通道,複用指的是一個程式可以同時監控多個檔案描述符(比如socket),當某個檔案描述符狀態發生變化(比如變得可讀或可寫),多路複用的函式將返回變化的檔案描述符。

這樣,在資料傳輸過程中,同一個程式中不同的任務都能被處理。特點是在資料傳輸過程中,程式能夠同時處理多個任務,提高了程式的效率。

select、poll、epoll 等都是 I/O 多路複用的具體實現。

以select/poll為例,程式透過將一個或多個fd傳遞給select或poll系統呼叫,阻塞在select操作上,這樣select/poll可以偵測多個fd是否處於就緒狀態。當有fd就緒時,立即回撥函式rollback,接下來就可以進行讀取。

一頓飯的事兒,搞懂Linux5種IO模型

就像是我想吃頓好的,於是選擇去吃自助餐,自助餐有很多餐區,我先看看哪個餐區有我想吃的菜,然後端著盤子去取就行了,一個人就可以取多個菜,肉、蔬菜、水果,什麼都能吃一點,而且不用怎麼等。

訊號驅動式IO(Signal-Driven I/O)

訊號驅動式IO利用訊號機制來進行資料傳輸。

程式首先告訴核心,當資料準備好時,請傳送一個SIGIO訊號。程式繼續執行其他任務,等到收到訊號後,再開始進行資料傳輸。

一頓飯的事兒,搞懂Linux5種IO模型

就像是我去吃飯,外帶,跟服務員打聲招呼,餐好了通知我,這時候我就可以去幹其它事情,餐備好之後,服務員通知我,我取餐就行了。

非同步IO(Asynchronous I/O)

非同步IO是指當發起一個IO操作後,系統會立即返回。非同步IO操作在後臺進行資料傳輸,資料傳輸完成後,系統將通知程式。這樣,在整個資料傳輸的過程中,程式都可以執行其他任務,不需要等待。

一頓飯的事兒,搞懂Linux5種IO模型



可以看到,阻塞非阻塞主要指的是等待資料這個過程應用程式需不需要掛起,同步非同步指的是等待資料和資料複製這兩個過程應用程式需不需要掛起,只有非同步IO做到了完全非同步。

參考:

[1].《Netty權威指南》

[2]. 《Netty核心原理與RPC實踐》

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2950390/,如需轉載,請註明出處,否則將追究法律責任。

相關文章