IO multiplexinghtml
IO multiplexing這個詞可能有點陌生,可是若是我說select,epoll,大概就都能明白了。有些地方也稱這種IO方式爲event driven IO。咱們都知道,select/epoll的好處就在於單個process就能夠同時處理多個網絡鏈接的IO。它的基本原理就是select/epoll這個function會不斷的輪詢所負責的全部socket,當某個socket有數據到達了,就通知用戶進程。它的流程如圖:web
當用戶進程調用了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。socket
ref1: http://blog.csdn.net/historyasamirror/article/details/5778378函數
ref2: http://www.cnblogs.com/Anker/p/3254269.html性能
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------spa
epoll的LT和ET模式操作系統
epoll是IO複用技術,自己是阻塞模式,可是它能同時監聽多個文件描述符所以能高效處理IO。
LT模式(水平觸發):當epoll_wait檢測到監聽文件描述符上有事件發生時通知應用程序,應用程序能夠不當即處理該事件,下次調用epoll_wait時該事件還會被通告直到該事件被處理;.net
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: http://blog.csdn.net/liuxuejiang158blog/article/details/12290725
ref2:http://www.cnblogs.com/Anker/p/3263780.html
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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: http://www.zhihu.com/question/19732473