除了可以採用多程序和多執行緒方法實現併發伺服器之外,還可以採用i/o多路復用技術。通過該技術,系統核心緩衝i/o資料,當某個i/o準備好後,系統通 知應用程式該i/o可讀或可寫,這樣應用程式可以馬上完成相應的i/o操作,而不需要等待系統完成相應i/o操作,從而應用程式不必因等待i/o操作而阻 塞。
與多程序和多執行緒技術相比,i/o多路復用技術的最大優勢是系統開銷小,系統不必建立程序/執行緒,也不必維護這些程序/執行緒,從而大大減小了系統的開銷。
對於i/o復用典型的應用如下:
(1)當客戶處理多個描述字時(一般是互動式輸入和網路套介面),必須使用i/o復用。
(2)當乙個客戶同時處理多個套介面時,而這種情況是可能的,但很少出現。
(3)如果乙個tcp伺服器既要處理監聽套介面,又要處理已連線套介面,一般也要用到i/o復用。
(4)如果乙個伺服器即要處理tcp,又要處理udp,一般要使用i/o復用。
(5)如果乙個伺服器要處理多個服務或多個協議,一般要使用i/o復用。
i/o復用呼叫select()或poll()函式,並在該函式上阻塞,等待資料報套介面可讀;當select()返回可讀條件時,呼叫recvfrom()將資料報拷貝到應用程式緩衝區中,
select比epoll效率差的原因:select是輪詢,epoll是觸發式的,所以效率高。
select:
1.socket數量限制:該模式可操作的socket數由fd_setsize決定,核心預設32*32=1024.
2.操作限制:通過遍歷fd_setsize(1024)個socket來完成排程,不管哪個socket是活躍的,都遍歷一遍.
poll:
1.socket數量幾乎無限制:該模式下的socket對應的fd列表由乙個陣列來儲存,大小不限(預設4k).
2.操作限制:同select.
epoll:
1.socket數量無限制:同poll
2.操作無限制:基於核心提供的反射模式,有活躍socket時,核心訪問該socket的callback,不需要遍歷輪詢.但是當所有socket都 活躍的時候,這時候所有的callback都被喚醒,會導致資源的競爭.既然都是要處理所有的socket,那麼遍歷是最簡單最有效的實現方式.
舉例來說:
對於im伺服器,伺服器和伺服器之間都是長鏈結,但數量不多,一般一台60\70個,比如採用ice這種架構設計,但請求相當頻繁和密集,這時候通過反射喚醒callback不一定比用select去遍歷處理更好.
對於web伺服器,都是瀏覽器客戶端發起的http短鏈結請求,數量很大,好一點的**動輒每分鐘上千個請求過來,同時伺服器端還有更多的閒 置等待超時的socket,這時候沒必要把全部的socket都遍歷處理,因為那些等待超時的請求是大多數的,這樣用epoll會更好.
支援乙個程序開啟大數目的socket描述符
select 最不能忍受的是乙個程序所開啟的fd是有一定限制的,由fd_setsize設定,預設值是1024。對於那些需要 支援的上萬連線數目的im伺服器來說顯然太少了。這時候你一是可以選擇修改這個巨集然後重新編譯核心,不過資料也同時指出這樣會帶來網路效率的下降,二是可 以選擇多程序的解決方案(傳統的 apache方案),不過雖然linux上面建立程序的代價比較小,但仍舊是不可忽視的,加上程序間資料同步遠比不上執行緒間同步的高效,所以也不是一種完美的方案。不過 epoll則沒有這個限制,它所支援的fd上限是最大可以開啟檔案的數目,這個數字一般遠大於2048,舉個例子,在1gb記憶體的機器上大約是10萬左右,具體數目可以cat /proc/sys/fs/file-max察看,一般來說這個數目和系統記憶體關係很大。
io效率不隨fd數目增加而線性下降
傳統的select/poll另乙個致命弱點就是當你擁有乙個很大的socket集合,不過由於網路延時,任一時間只有部分的socket是 「活躍」的,但是select/poll每次呼叫都會線性掃瞄全部的集合,導致效率呈現線性下降。但是epoll不存在這個問題,它只會對「活躍」的 socket進行操作---這是因為在核心實現中epoll是根據每個fd上面的callback函式實現的。那麼,只有「活躍」的socket才會主動 的去呼叫 callback函式,其他idle狀態socket則不會,在這點上,epoll實現了乙個「偽」aio,因為這時候推動力在os核心。在一些 benchmark中,如果所有的socket基本上都是活躍的---比如乙個高速lan環境,epoll並不比select/poll有什麼效率,相反,如果過多使用epoll_ctl,效率相比還有稍微的下降。但是一旦使用idle connections模擬wan環境,epoll的效率就遠在select/poll之上了。
select模式低效的原因
select 模式低效是由select的定義所決定的,與作業系統實現無關,任何核心在實現select時必須做輪循,才能知道這些socket的情況,這是會消耗 cpu 的。此外,當你擁有乙個很大socket集的時候,儘管任一時間只有小部分的socket是"活躍"的,但每次你都不得不將所有的socket填入到乙個 fd_set中,這也會消耗一些cpu,並且當select返回後,處理業務時你可能還需要做「上下文對映」,同樣也會有一些效能影響,因此 select比epoll相對低效。
epoll的適用情景就是大量的socket,但是活躍多不是很高的情況。
但是select的效率比較低,因為核心每次都要對select傳入的一組socket號做輪詢。而這篇文章將會介紹更加高效的epoll。
epoll的優點
沒有最大併發連線的限制,上限是最大可以開啟檔案的數目,這個數字一般遠大於2048, 一般來說這個數目和系統記憶體關係很大,具體數目可以cat /proc/sys/fs/file-max察看。
效率提公升,epoll最大的優點就在於它只管你「活躍」的連線,而跟連線總數無關,因此在實際的網路環境中,epoll的效率就會遠遠高於select和poll。
記憶體拷貝,epoll在這點上使用了「共享記憶體」,這個記憶體拷貝也省略了。
I O多路復用
一 五種i o模型 1 阻塞i o模型 最流行的i o模型是阻塞i o模型,預設情形下,所有套介面都是阻塞的。我們以資料報套介面為例來講解此模型 我們使用udp而不是tcp作為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單 要麼整個資料報已經收到,要麼還沒有。然而對於tcp來說,諸如套介面...
i o多路復用
最常見的i o多路復用就是 select poll epoll了,下面說說他們的一些特點和區別吧。select 可讀 可寫 異常三種檔案描述符集的申明和初始化。fd set readfds,writefds,exceptionfds fd zero readfds fd zero writefds ...
I O多路復用
我們都知道unix like 世界裡,一切皆檔案,而檔案是什麼呢?檔案就是一串二進位製流而已,不管socket,還是fifo 管道 終端,對我們來說,一切都是檔案,一切都是流。在資訊 交換的過程中,我們都是對這些流進行資料的收發操作,簡稱為i o操作 input and output 往流中讀出資料...