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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多路 IO 转接 :epoll 函数

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

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

#include <sys/epoll.h>

(2)函數(shù)
1)創(chuàng)建一個 epoll 句柄:

int epoll_create(int size)

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

int epfd = epoll_create(100);

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

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

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

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

聯(lián)合體

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

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

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

3)等待所監(jiān)控文件描述符上有事件的產(chǎn)生,類似于 select 函數(shù)調(diào)用。

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

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

struct epoll_event events[100];int ret = epoll_wait(epfd, events, 100, -1);if(ret > 0){for(int i = 0; i < ret; i++) //“高并發(fā)、少訪問”情況下,也可以保證高效率 {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)); } }

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。