io multiplexing
io multiplexing這個詞可能有點陌生,但是如果我說select,epoll,大概就都能明白了。有些地方也稱這種io方式為event driven io。我們都知道,select/epoll的好處就在於單個process就可以同時處理多個網路連線的io。它的基本原理就是select/epoll這個function會不斷的輪詢所負責的所有socket,當某個socket有資料到達了,就通知使用者程序。它的流程如圖:
當使用者程序呼叫了select,那麼整個程序會被block,而同時,kernel會「監視」所有select負責的socket,當任何乙個socket中的資料準備好了,select就會返回。這個時候使用者程序再呼叫read操作,將資料從kernel拷貝到使用者程序。
這個圖和blocking io的圖其實並沒有太大的不同,事實上,還更差一些。因為這裡需要使用兩個system call (select 和 recvfrom),而blocking io只呼叫了乙個system call (recvfrom)。但是,用select的優勢在於它可以同時處理多個connection。(多說一句。所以,如果處理的連線數不是很高的話,使用select/epoll的web server不一定比使用multi-threading + blocking io的web server效能更好,可能延遲還更大。select/epoll的優勢並不是對於單個連線能處理得更快,而是在於能處理更多的連線。)
在io multiplexing model中,實際中,對於每乙個socket,一般都設定成為non-blocking,但是,如上圖所示,整個使用者的process其實是一直被block的。只不過process是
被select這個函式block,而不是被socket io給block。
四種常見的i/o模型:阻塞i/o, 非阻塞i/o, i/o復用,非同步i/o。
詳見unp ch6.2或下面ref。
ref1:
ref2:
epoll的lt和et模式
epoll是io復用技術,本身是阻塞模式,但是它能同時監聽多個檔案描述符因此能高效處理io。
lt模式(水平觸發):當epoll_wait檢測到監聽檔案描述符上有事件發生時通知應用程式,應用程式可以不立即處理該事件,下次呼叫epoll_wait時該事件還會被通告直到該事件被處理;
et模式(邊緣觸發):當epoll_wait檢測到事件發生告知應用程式後應用程式必須立即處理該事件,後續的epoll_wait將不會再向應用程式告知這一事件。
二者的差異在於:
level-trigger模式下只要某個socket處於readable/writable狀態【相當於只要電平值是1】,無論什麼時候進行epoll_wait都會返回該socket;
而edge-trigger模式下只有某個socket從unreadable變為readable或從unwritable變為writable時【相當於電平由0變成1那一瞬間】,epoll_wait才會返回該socket。在epoll的et模式下,正確的讀寫方式為:讀:只要可讀,就一直讀,直到返回0,或者 errno = eagain;寫:只要可寫,就一直寫,直到資料傳送完,或者 errno = eagain。
et模式在很大程度上減少了epoll事件被重複觸發的次數,因此效率要比lt模式高。epoll工作在et模式的時候,必須使用非阻塞套介面,以避免由於乙個檔案控制代碼的阻塞讀/阻塞寫操作把處理多個檔案描述符的任務餓死。 (?)
ref1:
ref2:
select、poll、epoll之間的區別總結ref
ref2
select和poll都需要在返回後,通過遍歷檔案描述符集來獲取已經就緒的socket。事實上,同時連線的大量客戶端在一時刻可能只有很少的處於就緒狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降。
epoll不同於select和poll輪詢的方式,而是通過每個fd定義的**函式來實現的。只有就緒的fd才會執行**函式。
select,poll,epoll本質上都是同步i/o,因為他們都需要在讀寫事件就緒後自己負責進行讀寫,也就是說這個讀寫過程是阻塞的;
而非同步i/o則無需自己負責進行讀寫,非同步i/o的實現會負責把資料從核心拷貝到使用者空間。
比較同步、非同步、阻塞、非阻塞
阻塞,非阻塞:程序/執行緒要訪問的資料未就緒時,程序/執行緒是否需要等待;
同步,非同步:訪問資料的方式。同步需要主動讀寫資料,在讀寫資料的過程中還是會阻塞;非同步只需要i/o操作完成的通知,並不主動讀寫資料,由作業系統核心完成資料的讀寫。
對unix來講:阻塞式i/o(預設),非阻塞式i/o(nonblock),i/o復用(select/poll/epoll)都屬於同步i/o,因為它們在資料由核心空間複製回程序緩衝區時都是阻塞的(不能幹別的事)。只有非同步i/o模型(aio)是符合非同步i/o操作的含義的,即在(1) 資料準備完成 (2) 由核心空間拷貝回緩衝區後 通知程序,在等待通知的這段時間裡可以幹別的事。
ref:
epoll 實現I O復用
epoll是linux特有的i o復用函式,它能顯著提高程式在大量併發連線中只有少量活躍的情況下的系統cpu利用率 並且epoll使用一組函式來完成任務,而不是單個函式,它無須遍歷整個被偵聽的描述符集,只要遍歷那些核心i o時間非同步喚醒而加入ready佇列的描述符集合即可。但epoll需要使用乙個...
IO復用模型 epoll
參見 1.epoll模型簡介 epoll是linux多路服用io介面select poll的加強版,e對應的英文單詞就是enhancement,中文翻譯為增強,加強,提高,充實的意思。所以epoll模型會顯著提高程式在大量併發連線中只有少量活躍的情況下的系統cpu利用率。epoll把使用者關心的檔案...
IO復用 epoll函式
由於poll 和select 的侷限,2.6核心以上引用了event poll機制 就是說的epoll 雖然比前2個實現複雜得多,epoll解決了它們共有的基本效能問題,並增加了新的特性。poll 和select 每次呼叫的時候,都需要所有被監聽的檔案的描述符。核心必須遍歷所有被監視的檔案描述符。當...