1. 程式人生 > 實用技巧 >五種IO模型---轉載

五種IO模型---轉載

版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。
本文連結:https://blog.csdn.net/ZWE7616175/article/details/80591587


在網路環境下,通俗的講,將IO分為兩步
1.等;
2.資料搬遷。
如果要想提高IO效率,需要將等的時間降低。

五種IO模型包括:阻塞IO、非阻塞IO、訊號驅動IO、IO多路轉接、非同步IO。其中,前四個被稱為同步IO。

在介紹五種IO模型時,我會舉生活中釣魚的例子,加深理解。

1.阻塞IO(blocking I/O)

A拿著一支魚竿在河邊釣魚,並且一直在魚竿前等,在等的時候不做其他的事情,十分專心。只有魚上鉤的時,才結束掉等的動作,把魚釣上來。

在核心將資料準備好之前,系統呼叫會一直等待所有的套接字,預設的是阻塞方式。

其實,我們例子中所說的魚竿就是這一個檔案描述符。這個模型是我們最常見的,程式呼叫和我們編寫的基本程式是一致的。

fd=connect();
write(fd);
read(fd);
close(fd);1234

程式的read必須在write之後執行,當write阻塞住了,read就不能執行下去,一直處於等待狀態。

2.非阻塞IO(noblocking I/O)

B也在河邊釣魚,但是B不想將自己的所有時間都花費在釣魚上,在等魚上鉤這個時間段中,B也在做其他的事情(一會看看書,一會讀讀報紙,一會又去看其他人的釣魚等),但B在做這些事情的時候,每隔一個固定的時間檢查魚是否上鉤。一旦檢查到有魚上鉤,就停下手中的事情,把魚釣上來。

其實,B在檢查魚竿是否有魚,是一個輪詢的過程。

每次客戶詢問核心是否有資料準備好,即檔案描述符緩衝區是否就緒。當有資料報準備好時,就進行拷貝資料報的操作。當沒有資料報準備好時,也不阻塞程式,核心直接返回未準備就緒的訊號,等待使用者程式的下一個輪尋。

但是,輪尋對於CPU來說是較大的浪費,一般只有在特定的場景下才使用。

3.訊號驅動IO(signal blocking I/O)

C也在河邊釣魚,但與A、B不同的是,C比較聰明,他給魚竿上掛一個鈴鐺,當有魚上鉤的時候,這個鈴鐺就會被碰響,C就會將魚釣上來。

訊號驅動IO模型,應用程序告訴核心:當資料報準備好的時候,給我傳送一個訊號,對SIGIO訊號進行捕捉,並且呼叫我的訊號處理函式來獲取資料報。

4.IO多路轉接(I/O multiplexing)

D同樣也在河邊釣魚,但是D生活水平比較好,D拿了很多的魚竿,一次性有很多魚竿在等,D不斷的檢視每個魚竿是否有魚上鉤。增加了效率,減少了等待的時間。

IO多路轉接是多了一個select函式,select函式有一個引數是檔案描述符集合,對這些檔案描述符進行迴圈監聽,當某個檔案描述符就緒時,就對這個檔案描述符進行處理。

其中,select只負責等,recvfrom只負責拷貝。
IO多路轉接是屬於阻塞IO,但可以對多個檔案描述符進行阻塞監聽,所以效率較阻塞IO的高。

5.非同步IO(asynchronous I/O)

E也想釣魚,但E有事情,於是他僱來了F,讓F幫他等待魚上鉤,一旦有魚上鉤,F就打電話給E,E就會將魚釣上去。

當應用程式呼叫aio_read時,核心一方面去取資料報內容返回,另一方面將程式控制權還給應用程序,應用程序繼續處理其他事情,是一種非阻塞的狀態。

當核心中有資料報就緒時,由核心將資料報拷貝到應用程式中,返回aio_read中定義好的函式處理程式。

很少有Linux系統支援,Windows的IOCP就是該模型。

可以看出,阻塞程度:阻塞IO>非阻塞IO>多路轉接IO>訊號驅動IO>非同步IO,效率是由低到高的