linux 五種IO模型(IO多路復用)

2022-04-28 22:42:16 字數 3138 閱讀 2032

側重狀態。

阻塞呼叫是指呼叫後對方一直沒有給你回覆,你一直等著,什麼事都不能幹。

非阻塞呼叫指在呼叫後一直沒有給你回覆,你每一段時間就問一次,你在這期間可以幹別的。

側重方式。

同步:甲方請求一次,乙方應答一次」這樣的有序序列處理業務,只有當「一次請求一次應答」的過程結束才可以發生下一次的「一次請求一次應答」,那麼就說他們採用的是同步。

非同步:如果甲方只要有需要,就會傳送請求,不管上次請求有沒有得到乙方應答。而乙方只要甲方有請求就會接受,不是等這次請求處理完畢再接受甲方新請求。這樣請求應答分開的序列,就可以認為是非同步。非同步情況下,請求和應答不需要一致進行,可能甲方後請求的業務,卻先得到乙方的應答。同步是線性的,而非同步可以認為是併發的。

每一種方式肯定對應著相應的狀態。

如果請求量大, 資料量大,那麼同步阻塞肯定會影響效能。

阻塞io:就是那種recv, read,一直等,等到有了資料才返回;

非阻塞io:就是立即返回,設定描述符為非阻塞,但是要程序自己一直檢查是否可讀;

io復用其實也是阻塞的,不過可以用來等很多描述符,比起阻塞有了進步,可以算有點非同步了,但需要阻塞著檢查是否可讀。對同乙個描述符的io操作也是有序的。

訊號驅動採用訊號機制等待,有了更多的進步,不用監視描述符了,而且不用阻塞著等待資料到來,被動等待訊號通知,由訊號處理程式處理。但對同乙個描述符的io操作還是有序的。

非同步io,傳送io請求後,不用等了,也不再需要傳送io請求獲取結果了。等到通知後,其實是系統幫你把資料讀取好了的,你等到的通知也不再是要求你去讀寫io了,而是告訴你io請求過程已經結束了。你要做的就是可以處理資料了。且同乙個描述符上可能同時存在很多請求。

阻塞i/o模型

老李去火車站買票,排隊三天買到一張退票。

耗費:在車站一直排隊,沒法幹別的事。

非阻塞i/o模型

老李去火車站買票,火車站說沒有,每隔12小時去火車站問有沒有退票,三天後買到一張票。

耗費:往返車站路上耗費時間,其他時間可以做別的事。

i/o復用模型

訊號驅動i/o模型

老李去火車站買票,給售票員留下**,有票後,售票員**通知老李,然後老李去火車站交錢領票。

耗費:無需打**

非同步i/o模型

老李去火車站買票,給售票員留下**,有票後,售票員**通知老李並快遞送票上門。

耗費:無需打**

如果乙個i/o流進來,我們就開啟乙個程序處理這個i/o流。那麼假設現在有一百萬個i/o流進來,那我們就需要開啟一百萬個程序一一對應處理這些i/o流(——這就是傳統意義下的多程序併發處理)。思考一下,一百萬個程序,你的cpu占有率會多高,這個實現方式及其的不合理。所以人們提出了i/o多路復用這個模型,乙個執行緒,通過記錄i/o流的狀態來同時管理多個i/o,可以提高伺服器的吞吐能力。

fd是什麼

操作檔案的描述符。

fd的型別為int, < 0 為非法值, >=0 為合法值。在linux中,乙個程序預設可以開啟的檔案數為1024個,fd的範圍為0~1023。

呼叫過程:

select函式的呼叫過程

a. 從使用者空間將fd_set拷貝到核心空間

b. 註冊**函式

c. 呼叫其對應的poll方法

d. poll方法會返回乙個描述讀寫是否就緒的mask掩碼,根據這個mask掩碼給fd_set賦值。

e. 如果遍歷完所有的fd都沒有返回乙個可讀寫的mask掩碼,就會讓select的程序進入休眠模式,直到發現可讀寫的資源後,重新喚醒等待佇列上休眠的程序。如果在規定時間內都沒有喚醒休眠程序,那麼程序會被喚醒重新獲得cpu,再去遍歷一次fd。

f. 將fd_set從核心空間拷貝到使用者空間

缺點:

兩次拷貝耗時(從使用者空間將fd_set拷貝到核心空間, 將fd_set從核心空間拷貝到使用者空間)

輪詢所有fd耗時(遍歷完所有的fd檢視是否返回乙個可讀寫的mask掩碼)

支援的檔案描述符太小(1024)

優點:

跨平台支援

優點:

連線數(也就是檔案描述符)沒有限制(鍊錶儲存)

poll函式的呼叫過程與select完全一致

缺點:

大量拷貝,水平觸發(當報告了fd沒有被處理,會重複報告,很耗效能)

epoll的et與lt模式

lt:延遲處理,當檢測到描述符事件通知應用程式,應用程式不立即處理該事件。那麼下次會再次通知應用程式此事件。

et:立即處理,當檢測到描述符事件通知應用程式,應用程式會立即處理。

et模式減少了epoll被重複觸發的次數,效率比lt高。我們在使用et的時候,必須採用非阻塞套介面,避免某檔案控制代碼在阻塞讀或阻塞寫的時候將其他檔案描述符的任務餓死。

epoll的函式呼叫流程

a. 當呼叫epoll_wait函式的時候,系統會建立乙個epoll物件,每個物件有乙個evenpoll型別的結構體與之對應,結構體成員結構如下。

rbn,代表將要通過epoll_ctl向epll物件中新增的事件。這些事情都是掛載在紅黑樹中。

rdlist,裡面存放的是將要發生的事件。

b. 檔案的fd狀態發生改變,就會觸發fd上的**函式

c. **函式將相應的fd加入到rdlist,導致rdlist不空,程序被喚醒,epoll_wait繼續執行。

d. 有乙個事件轉移函式——ep_events_transfer,它會將rdlist的資料拷貝到txlist上,並將rdlist的資料清空。

e. ep_send_events函式,它掃瞄txlist的每個資料,呼叫關聯fd對應的poll方法去取fd中較新的事件,將取得的事件和對應的fd傳送到使用者空間。如果fd是lt模式的話,會被txlist的該資料重新放回rdlist,等待下一次繼續觸發呼叫。

epoll的優點

沒有最大併發連線的限制

只有活躍可用的fd才會呼叫callback函式

記憶體拷貝是利用mmap()檔案對映記憶體的方式加速與核心空間的訊息傳遞,減少複製開銷。(核心與使用者空間共享一塊記憶體)

只有存在大量空閒連線和不活躍的連線的時候,使用epoll的效率才會比select/poll高。

所以epoll相比select和poll,相當的利用最大連線數並節省記憶體

Linux五種IO模型

五種io模型的理解 阻塞io 收銀台等待 在核心將資料準備好之前,系統調 會 直等待.所有的套接字,預設都是阻塞 式.阻塞io 座位等待 往往需要程式設計師迴圈的方式反覆嘗試讀寫檔案描述符,這個過程稱為輪詢.訊號驅動io 等服務員叫 核心將資料準備好的時候,使 sigio訊號通知應用程式進行io操作...

Linux 五種I O模型

首先,我們來看一下,有哪五種i o模型 小結 非阻塞i o,記錄鎖,系統v流機制,i o多路轉接 也叫i o多路復用 readv和writev函式以及儲存對映i o mmap 這些統稱為高階i o。首先,我們來看乙個介面 int fcntl int fd,int cmd,arg 功能 針對描述符提供...

五種IO模型

再講io模型之前,給大家舉乙個釣魚的例子。張三去釣魚,他釣魚的時候一動不動,一直看著魚竿,看有沒有動,無論是誰叫他,他都不動,只有等魚梢動了 魚上鉤了 他才會動 李四去釣魚,他沒有像張三那樣瓷楞著,只是時不時的輪詢檢查魚竿有沒有動。一直在動。王五也來釣魚,他就比較聰明了,在魚竿上掛個鈴鐺,只要鈴鐺響...