Linux企業級開發技術(1)——epoll企業級開發之簡介

尹成發表於2014-09-23

 

Epoll是當前在 Linux 下開發大規模併發網路程式的熱門人選, Epoll 在 Linux2.6 核心中正式引入。和 select 相似,是高效 I/O 多路複用技術。

其實在 Linux 下設計併發網路程式,有多種模型:如典型的 Apache 模型( Process Per Connection ,簡稱 PPC ), TPC ( Thread PerConnection )模型,以及 select 模型和 poll 模型

 

為了對比Epoll 的優點,下面列舉常用模型的特點:

1、 PPC/TPC 模型

這兩種模型思想類似,就是讓每一個到來的連線作為一個單獨的任務,不影響主程式。只是 PPC 是為它開了一個程式,而 TPC 開了一個執行緒。但是其代價是,連線數增多了之後,程式 / 執行緒切換開銷就會增加。因此這類模型能接受的最大連線數都不會高,一般在幾百個左右。

 

2 、select 模型

最大併發數限制,因為一個程式所開啟的 FD (檔案描述符)是有限制的,由 FD_SETSIZE 設定,預設值是 1024/2048 ,因此 Select 模型的最大併發數就被相應限制了。儘管我們可以修改 FD_SETSIZE但是會產生效率問題。

select 每次呼叫都會線性掃描全部的 FD 集合,這樣效率就會呈現線性下降,所以把FD_SETSIZE 改大的後果就是,會造成超市

核心 / 使用者空間記憶體拷貝問題,如何讓核心把 FD 訊息通知給使用者空間呢?在這個問題上 select 採取了記憶體拷貝方法。

3 、poll 模型

基本上效率和 select 是相同的,同樣具有select 存在的缺點缺點。

 

Epoll 沒有最大併發連線的限制,上限是最大可以開啟檔案的數目,這個數字一般遠大於 2048, 一般來說這個數目和系統記憶體關係很大,具體數目可以 cat /proc/sys/fs/file-max 察看。

Epoll 最大的優點就在於它只管你“活躍”的連線 ,而跟連線總數無關,因此在實際的網路環境中, Epoll 的效率就會遠遠高於 select 和 poll 。

Epoll 在記憶體管理上使用了“共享記憶體 ”,提高了效率。

 

 

Epoll 的高效和其資料結構的設計是密不可分的。

首先回憶一下 select 模型,當有 I/O 事件到來時, select 通知應用程式有事件到了快去處理,而應用程式必須輪詢所有的 FD 集合,測試每個 FD 是否有事件發生,並處理事件;程式碼像下面這樣:

 

int res = select(maxfd+1, &readfds,NULL, NULL, 120);
if (res > 0)
{
   for (int i = 0; i < MAX_CONNECTION; i++)
    {
       if (FD_ISSET(allConnection[i], &readfds))
       {
           handleEvent(allConnection[i]);
       }
    }
}
// if(res == 0) handle timeout, res < 0handle error

Epoll 不僅會告訴應用程式有I/0 事件到來,還會告訴應用程式相關的資訊,這些資訊是應用程式填充的,因此根據這些資訊應用程式就能直接定位到事件,而不必遍歷整個FD 集合。

int res = epoll_wait(epfd, events, 20,120);
for (int i = 0; i < res;i++)
{
   handleEvent(events[n]);
}

Epoll 速度快和其資料結構密不可分,其關鍵資料結構就是:

struct epoll_event {
   __uint32_t events;      // Epollevents
   epoll_data_t data;      // Userdata variable
};
typedef union epoll_data {
   void *ptr;
   int fd;
   __uint32_t u32;
   __uint64_t u64;
} epoll_data_t;


可見 epoll_data 是一個 union 結構體 , 藉助於它應用程式可以儲存很多型別的資訊 :fd 、指標等等。有了它,應用程式就可以直接定位目標了。

相關文章