浅析epoll – epoll函数深入讲解
前一篇大致講了一下epoll是個(gè)什么東西,優(yōu)點(diǎn)等內(nèi)容,這篇延續(xù)上一篇的內(nèi)容,主要是分析epoll的函數(shù),epoll高性能的深入分析。
epoll的三大函數(shù)
1.創(chuàng)建epoll fd函數(shù)
int epoll_create(int size);epoll_create()創(chuàng)建一個(gè)epoll的事例,通知內(nèi)核需要監(jiān)聽(tīng)size個(gè)fd。size指的并不是最大的后備存儲(chǔ)設(shè)備,而是衡量?jī)?nèi)核內(nèi)部結(jié)構(gòu)大小的一個(gè)提示。當(dāng)創(chuàng)建成功后,會(huì)占用一個(gè)fd,所以記得在使用完之后調(diào)用close(),否則fd可能會(huì)被耗盡。
Note:自從Linux2.6.8版本以后,size值其實(shí)是沒(méi)什么用的,不過(guò)要大于0,因?yàn)閮?nèi)核可以動(dòng)態(tài)的分配大小,所以不需要size這個(gè)提示了。
創(chuàng)建還有另外一個(gè)函數(shù)
int epoll_create1(int flag);這個(gè)函數(shù)是在linux 2.6.27中加入的,當(dāng)你在看陳碩的muduo時(shí)可以看到這個(gè)函數(shù),其實(shí)它和epoll_create差不多,不同的是epoll_create1函數(shù)的參數(shù)是flag,當(dāng)flag是0時(shí),表示和epoll_create函數(shù)完全一樣,不需要size的提示了。
當(dāng)flag = EPOLL_CLOEXEC,創(chuàng)建的epfd會(huì)設(shè)置FD_CLOEXEC
當(dāng)flag = EPOLL_NONBLOCK,創(chuàng)建的epfd會(huì)設(shè)置為非阻塞
一般用法都是使用EPOLL_CLOEXEC.
Note:關(guān)于FD_CLOEXEC,現(xiàn)在網(wǎng)上好多都說(shuō)的有點(diǎn)問(wèn)題,我翻閱了一些資料,請(qǐng)教了一些人,大約明白它的意思了。
它是fd的一個(gè)標(biāo)識(shí)說(shuō)明,用來(lái)設(shè)置文件close-on-exec狀態(tài)的。當(dāng)close-on-exec狀態(tài)為0時(shí),調(diào)用exec時(shí),fd不會(huì)被關(guān)閉;狀態(tài)非零時(shí)則會(huì)被關(guān)閉,這樣做可以防止fd泄露給執(zhí)行exec后的進(jìn)程。關(guān)于exec的用法,大家可以去自己查閱下,或者直接man exec。
2.epoll事件的注冊(cè)函數(shù)
int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);select是在監(jiān)聽(tīng)時(shí)告訴內(nèi)核要監(jiān)聽(tīng)的事件,而epoll_ctl是先注冊(cè)需要監(jiān)聽(tīng)的事件。
第一個(gè)參數(shù)epfd,為epoll_create返回的的epoll fd。
第二個(gè)參數(shù)op表示操作值。有三個(gè)操作類型,
EPOLL_CTL_ADD? // 注冊(cè)目標(biāo)fd到epfd中,同時(shí)關(guān)聯(lián)內(nèi)部event到fd上EPOLL_CTL_MOD // 修改已經(jīng)注冊(cè)到fd的監(jiān)聽(tīng)事件EPOLL_CTL_DEL // 從epfd中刪除/移除已注冊(cè)的fd,event可以被忽略,也可以為NULL第三個(gè)參數(shù)fd表示需要監(jiān)聽(tīng)的fd。
第四個(gè)參數(shù)event表示需要監(jiān)聽(tīng)的事件。
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 */ };event參數(shù)是一個(gè)枚舉的集合,可以用” | “來(lái)增加事件類型,枚舉如下:
EPOLLIN:表示關(guān)聯(lián)的fd可以進(jìn)行讀操作了。
EPOLLOUT:表示關(guān)聯(lián)的fd可以進(jìn)行寫操作了。
EPOLLRDHUP(since?Linux?2.6.17):表示套接字關(guān)閉了連接,或者關(guān)閉了正寫一半的連接。
EPOLLPRI:表示關(guān)聯(lián)的fd有緊急優(yōu)先事件可以進(jìn)行讀操作了。
EPOLLERR:表示關(guān)聯(lián)的fd發(fā)生了錯(cuò)誤,epoll_wait會(huì)一直等待這個(gè)事件,所以一般沒(méi)必要設(shè)置這個(gè)屬性。
EPOLLHUP:表示關(guān)聯(lián)的fd掛起了,epoll_wait會(huì)一直等待這個(gè)事件,所以一般沒(méi)必要設(shè)置這個(gè)屬性。
EPOLLET:設(shè)置關(guān)聯(lián)的fd為ET的工作方式,epoll的默認(rèn)工作方式是LT。
EPOLLONESHOT (since Linux 2.6.2):設(shè)置關(guān)聯(lián)的fd為one-shot的工作方式。表示只監(jiān)聽(tīng)一次事件,如果要再次監(jiān)聽(tīng),需要把socket放入到epoll隊(duì)列中。
3.epoll等待事件函數(shù)
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout,? const sigset_t *sigmask);
上面兩個(gè)函數(shù)的參數(shù)含義:
第一個(gè)參數(shù):表示epoll_wait等待epfd上的事件
第二個(gè)參數(shù):events指針攜帶有epoll_data_t數(shù)據(jù)
第三個(gè)參數(shù):maxevents告訴內(nèi)核events有多大,該值必須大于0
第四個(gè)參數(shù):timeout表示超時(shí)時(shí)間(單位:毫秒)
epoll_pwait(since linux 2.6.19)允許一個(gè)應(yīng)用程序安全的等待,直到fd設(shè)備準(zhǔn)備就緒,或者捕獲到一個(gè)信號(hào)量。其中sigmask表示要捕獲的信號(hào)量。
函數(shù)如果等待成功,則返回fd的數(shù)字;0表示等待fd超時(shí),其他錯(cuò)誤號(hào)請(qǐng)查看errno
函數(shù)到這里就講完了,下一篇會(huì)寫一個(gè)例子給大家看下這些函數(shù)是如何使用的。
轉(zhuǎn)載請(qǐng)注明:C++愛(ài)好者博客???淺析epoll – epoll函數(shù)深入講解
總結(jié)
以上是生活随笔為你收集整理的浅析epoll – epoll函数深入讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: realarm Android系统编译后
- 下一篇: 浅析epoll-为何多路复用I/O要使用