inux 高併發事件觸發處理 — epoll

 轉載: https://blog.csdn.net/qq_19923217/article/details/81943705

版權聲明:遵循 CC 4.0 BY-SA 版權協議

 

一. 概述
epoll 是 Linux 內核爲處理大批量文件描述符而作了改進的 poll,是 Linux 下多路複用 IO接口 select/poll 的增強版本

在 linux 的網絡編程中,很長時間都在使用 select 來做事件觸發。在 2.6 內核中,有一種替換它的機制,就是 epoll。

select 與 epoll 區別概述
(1) 函數使用上:epoll 使用一組函數來完成任務,而不是單個函數

(2) 效率:select 使用輪詢來處理,隨着監聽 fd 數目的增加而降低效率。而 epoll 把用戶關心的文件描述符事件放在內核裏的一個事件表中,只需要一個額外的文件描述符來標識內核中的這個事件表即可。

二. epoll 接口
epoll 事件觸發併發處理操作過程總共需要三個接口,下面詳細說明這三個接口的使用。

頭文件
#include <sys/epoll.h>
1
1 int epoll_create(int size);
前面說到 epoll 使用內核事件表來實現 I/O 複用,所以需要一個額外的文件描述符來標識使用的內核事件表。

epoll_create 函數就是用來獲取內核事件表的特殊文件描述符,該函數返回的文件描述符將用作其他 epoll 系統調用的第一個參數,以指定要訪問的內核事件表。

2 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll 的事件註冊函數,用來操作內核事件表。它不同與 select() 是在監聽事件時告訴內核要監聽什麼類型的事件,而是在這裏先註冊要監聽的事件類型。

參數含義:
1. epfd: 要操作的內核事件表的文件描述符,即 epoll_create 的返回值
2. op:指定操作類型,操作類型有三種:
-> EPOLL_CTL_ADD:往內核事件表中註冊指定fd 相關的事件
-> EPOLL_CTL_MOD:修改指定 fd 上的註冊事件
-> EPOLL_CTL_DEL:刪除指定 fd 的註冊事件
3. fd:所要操作的文件描述符,也就是要內核事件表中監聽的 fd
4. event:指定所要監聽的事件類型,epoll_event 結構指針類型。
1
2
3
4
5
6
7
struct epoll_even 結構如下:
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;

struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
1
2
3
4
5
6
7
8
9
10
11
其中 events 成員描述事件類型,可以是以下幾種類型宏的集合:

EPOLLIN:表示對應的文件描述符可以讀(包括對端SOCKET正常關閉);
EPOLLOUT:表示對應的文件描述符可以寫;
EPOLLPRI:表示對應的文件描述符有緊急的數據可讀(這裏應該表示有帶外數據到來);
EPOLLERR:表示對應的文件描述符發生錯誤;
EPOLLHUP:表示對應的文件描述符被掛斷;
EPOLLET: 將EPOLL設爲邊緣觸發(Edge Triggered)模式,這是相對於水平觸發(Level Triggered)來說的。
EPOLLONESHOT:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到EPOLL隊列裏
1
2
3
4
5
6
7
返回值
epoll_ctl 成功時返回 0,失敗則返回 -1,並設置 errno

3 int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);
等待事件的發生,它在一段超時時間之內等待一組文件描述符上的事件,epoll_wait 函數如果檢測到事件,就將所有就緒的事件從內核事件表(epfd 參數決定)中複製到第二個參數 events 指向的數組中。

參數
(1) epfd
要操作的內核事件表的文件描述符,即 epoll_create 的返回值

(2) events
內核事件表中得到的檢測事件集合

(3) maxevents & timeout
maxevents 告訴內核 events 的最大 size,timeout 指定超時時間

返回值
成功時返回就緒的文件描述符的個數,失敗返回 -1 並設置 errno

三. epoll 工作模式
epoll 對文件描述符的操作有兩種模式:LT(level trigger)和 ET(edge trigger)。LT 模式是默認模式,LT 模式與 ET 模式的區別如下:

  LT模式:電平觸發,當 epoll_wait 檢測到描述符事件發生並將此事件通知應用程序,應用程序可以不立即處理該事件。下次調用 epoll_wait 時,會再次響應應用程序並通知此事件。

  ET模式:邊沿觸發,當 epoll_wait 檢測到描述符事件發生並將此事件通知應用程序,應用程序必須立即處理該事件。如果不處理,下次調用 epoll_wait 時,不會再次響應應用程序並通知此事件。

  ET 模式在很大程度上減少了 epoll 事件被重複觸發的次數,因此效率要比 LT 模式高。epoll 工作在 ET 模式的時候,必須使用非阻塞套接口,以避免由於一個文件句柄的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死。
————————————————
版權聲明:本文爲CSDN博主「歲月斑駁7」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_19923217/article/details/81943705

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章