1. epoll 是何方神聖?
epoll 可是當前在 linux 下開發大規模併發網路程式的熱門人選, epoll 在 linux2.6 核心中正式引入,和 select 相似,其實都 i/o 多路復用技術而已 ,並沒有什麼神秘的。
其實在 linux 下設計併發網路程式,向來不缺少方法,比如典型的 apache 模型( process per connection ,簡稱 ppc ), tpc ( thread per connection )模型,以及 select 模型和 poll 模型,那為何還要再引入 epoll 這個東東呢?那還是有得說說的 …
2. 常用模型的缺點
如果不擺出來其他模型的缺點,怎麼能對比出 epoll 的優點呢。
2.1 ppc/tpc 模型
這兩種模型思想類似,就是讓每乙個到來的連線一邊自己做事去,別再來煩我 。只是 ppc 是為它開了乙個程序,而 tpc 開了乙個執行緒。可是別煩我是有代價的,它要時間和空間啊,連線多了之後,那麼多的程序 / 執行緒切換,這開銷就上來了;因此這類模型能接受的最大連線數都不會高,一般在幾百個左右。
2.2 select 模型
1. 最大併發數限制,因為乙個程序所開啟的 fd (檔案描述符)是有限制的,由 fd_setsize 設定,預設值是 1024/2048 ,因此 select 模型的最大併發數就被相應限制了。自己改改這個 fd_setsize ?想法雖好,可是先看看下面吧 …
2. 效率問題, select 每次呼叫都會線性掃瞄全部的 fd 集合,這樣效率就會呈現線性下降,把 fd_setsize 改大的後果就是,大家都慢慢來,什麼?都超時了??!!
3. 核心 / 使用者空間 記憶體拷貝問題,如何讓核心把 fd 訊息通知給使用者空間呢?在這個問題上 select 採取了記憶體拷貝方法。
2.3 poll 模型
基本上效率和 select 是相同的, select 缺點的 2 和 3 它都沒有改掉。
3. epoll 的提公升
把其他模型逐個批判了一下,再來看看 epoll 的改進之處吧,其實把 select 的缺點反過來那就是 epoll 的優點了。
3.1. epoll 沒有最大併發連線的限制,上限是最大可以開啟檔案的數目,這個數字一般遠大於 2048, 一般來說這個數目和系統記憶體關係很大 ,具體數目可以 cat /proc/sys/fs/file-max 察看。
3.2. 效率提公升, epoll 最大的優點就在於它只管你「活躍」的連線 ,而跟連線總數無關,因此在實際的網路環境中, epoll 的效率就會遠遠高於 select 和 poll 。
3.3. 記憶體拷貝, epoll 在這點上使用了「共享記憶體 」,這個記憶體拷貝也省略了。
4. epoll 為什麼高效
epoll 的高效和其資料結構的設計是密不可分的,這個下面就會提到。
首先回憶一下 select 模型,當有 i/o 事件到來時, select 通知應用程式有事件到了快去處理,而應用程式必須輪詢所有的 fd 集合,測試每個 fd 是否有事件發生,並處理事件;**像下面這樣:
int res = select(maxfd+1, &readfds, null, null, 120);
if (res > 0) }
} // if(res == 0) handle timeout, res < 0 handle error
epoll 不僅會告訴應用程式有i/0 事件到來,還會告訴應用程式相關的資訊,這些資訊是應用程式填充的,因此根據這些資訊應用程式就能直接定位到事件,而不必遍歷整個fd 集合。
int res = epoll_wait(epfd, events, 20, 120);
for (int i = 0; i < res;i++)
5. epoll 關鍵資料結構
前面提到 epoll 速度快和其資料結構密不可分,其關鍵資料結構就是:
struct epoll_event ;
typedef union epoll_data epoll_data_t;
可見 epoll_data 是乙個 union 結構體 , 借助於它應用程式可以儲存很多態別的資訊 :fd 、指標等等。有了它,應用程式就可以直接定位目標了。
6. 使用 epoll
既然 epoll 相比 select 這麼好,那麼用起來如何呢?會不會很繁瑣啊 … 先看看下面的三個函式吧,就知道 epoll 的易用了。
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event );
控制某個 epoll 檔案描述符上的事件:註冊、修改、刪除。其中引數 epfd 是 epoll_create() 建立 epoll 專用的檔案描述符。相對於 select 模型中的 fd_set 和 fd_clr 巨集。
int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout);
等待 i/o 事件的發生;引數說明:
epfd: 由 epoll_create() 生成的 epoll 專用的檔案描述符;
epoll_event: 用於回傳代處理事件的陣列;
maxevents: 每次能處理的事件數;
timeout: 等待 i/o 事件發生的超時值;
返回發生事件數。
相對於 select 模型中的 select 函式。
7. 例子程式
下面是乙個簡單 echo server 的例子程式,麻雀雖小,五臟俱全,還包含了乙個簡單的超時檢查機制,簡潔起見沒有做錯誤處理。
linux epoll技術介紹
在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。在linux新的核心中,有了一種替換它的機制,就是epoll。相比於select,epoll最大的好處在於它不會隨著監聽fd數目的增長而降低效率。因為在核心中的select實現中,它是採用輪詢來處理的,輪詢的fd數目越多,自然...
ssh 介紹 和使用 程式不掛起
目錄 ssh的安全機制 ssh的安裝 啟動伺服器的ssh服務 ssh兩種級別的遠端登入 ssh的高階應用 secure shell ssh 是由 ietf the internet engineering task force 制定的建立在應用層基礎上的安全網路協議。它是專為遠端登入會話 甚至可以用...
程式結構和分支語句介紹
程式的結構及分類 分支語句介紹 if語句介紹 switch語句介紹 迴圈語句介紹 當 型迴圈while 直到 型迴圈do.while 最常用的迴圈for 程式的結構化是乙個設計思想,規定了一套方法,是程式具有合理的結構,以保證和驗證程式的正確性。這種方法要求程式設計者布恩那個隨心所欲的編寫程式,而要...