日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多路 IO 转接 :epoll 函数

發布時間:2024/9/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多路 IO 转接 :epoll 函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

因為 select 和 poll 的返回值特性,所以想判斷到底哪個文件描述符發生了事件,需要遍歷文件描述符表,因此,在“高并發、少訪問”情況下,比如 1000 個連接,就 3 個發了數據,select 和 poll 效率就很低。
理想狀態:內核直接告訴我“哪個文件描述符”發生了“什么事件”:此功能對應于epoll 模型。
(1)頭文件

#include <sys/epoll.h>

(2)函數
1)創建一個 epoll 句柄:

int epoll_create(int size)

參數: 監聽文件描述符的數目(是一個建議值,內核可能會適時擴充)。
返回值:一個文件描述符,指向一個紅黑樹的樹根(參數 size 其實就是反應了樹的大小)。
使用:

int epfd = epoll_create(100);

2)控制某個 epoll 監控的文件描述符上的事件:注冊、修改、刪除。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)

參數 1:epoll 句柄,epoll_create 函數返回值。
參數 2: 用 3 個宏,表示執行動作 (控制樹上結點),
EPOLL_CTL_ADD :注冊新的 fd 到 epfd (上樹:添加結點);
EPOLL_CTL_MOD :修改已經注冊的 fd 的監聽事件 (修改結點);
EPOLL_CTL_DEL :從 epfd 刪除一個 fd (下樹:刪除結點)。
參數 3:f要監聽的文件描述符(即 參數 2 中控制的結點)
參數 4: 告訴內核需要監聽誰的什么事件 ,是傳入參數。

struct epoll_event {__uint32_t events; // 要監聽的事件: EPOLLIN (讀) / EPOLLOUT(寫) / EPOLLERRepoll_data_t data; // 返回事件聯合體:返回什么東西};

聯合體

typedef union epoll_data { void *ptr; int fd; // 返回有事件的文件描述符,其實就是參數 3uint32_t u32;uint64_t u64;} epoll_data_t;

返回值:成功返回0; 失敗返回-1,并設置 errno。
使用:

struct epoll_event evt; evt. events = EPOLLIN; evt. data.fd = lfd; // 結構體賦值 epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &evt); // 添加結點,監聽 lfd

3)等待所監控文件描述符上有事件的產生,類似于 select 函數調用。

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)

參數 1:epoll 句柄,epoll_create 函數返回值。
參數 2:struct epoll_event *events
注意:這里的參數2與 epoll_ctl 函數參數 4 的區別:
epoll_ctl 函數 參數 4:是我告訴內核,我想監聽某個文件描述符的某個事件,因此,使用上是傳入參數,先定義賦值,再傳入結構體地址(本質);
epoll_wait 函數 參數 2:目的是讓內核告訴我哪些文件描述符發生了哪些事件,使用上是傳出參數,因為數量多個,因此本質是結構體數組首地址。
參數 3:結構體數組容量
參數 4: int 型 : -1代表永久阻塞,直到監控事件發生;0代表立即返回,不阻塞進程; > 0代表等待指定的毫秒數。
返回值:成功返回所監聽的所有的滿足條件的文件描述符總數量;失敗返回 -1,設置 errno。
使用:

struct epoll_event events[100];int ret = epoll_wait(epfd, events, 100, -1);if(ret > 0){for(int i = 0; i < ret; i++) //“高并發、少訪問”情況下,也可以保證高效率 {if(events[i].data.fd == lfd)accept(events[i].data.fd, 獲得客戶端信息); if(events[i].data.fd == cfd)read(events[i].data.fd, buf, sizeof(buf)); } }

總結

以上是生活随笔為你收集整理的多路 IO 转接 :epoll 函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。