epoll相關(guān)

epoll 相關(guān)

標(biāo)簽(空格分隔): linux c/c++


1.epoll_create調(diào)用

int epoll_create(int size);
int epoll_create1(int flags);
  • 第一個(gè)函數(shù)epoll_create調(diào)用是比較常用的調(diào)用,第二個(gè)調(diào)用是改進(jìn)版本。內(nèi)核版本在2.9以及之后才能夠使用婶溯。
  • 調(diào)用成功的返回值,是一個(gè)文件描述符(非負(fù)整數(shù)),指向一個(gè)epoll實(shí)例绳泉,這個(gè)文件描述符代表這后續(xù)對(duì)于epoll相關(guān)接口的引用蓄氧。需要在使用結(jié)束后調(diào)用close關(guān)閉文件描述符弧满。
  • 調(diào)用出現(xiàn)錯(cuò)誤的返回值是-1,并可以在全局變量error中查看錯(cuò)誤信息俊庇。
  • 第一個(gè)調(diào)用的參數(shù)size是,調(diào)用者在后續(xù)使用epoll添加感興趣的文件描述符個(gè)數(shù)的大小甲葬,這個(gè)是一個(gè)給系統(tǒng)初次分配epoll監(jiān)控文件描述符數(shù)據(jù)結(jié)構(gòu)的內(nèi)存空間的一個(gè)參考值廊勃,但是如果后來(lái)調(diào)用者,監(jiān)聽(tīng)的事件超過(guò)這個(gè)范圍演顾,那么系統(tǒng)會(huì)額外的分配空間的供搀。
    總的來(lái)說(shuō)這個(gè)值只是操作系統(tǒng)的參考值。
  • epoll_create1參數(shù)是一個(gè)文件描述符標(biāo)志钠至,如果為0那么和 epoll_create(0)一樣。

2 epoll_ctl調(diào)用

2.1函數(shù)原型

#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

2.2參數(shù)說(shuō)明

2.2.1 event參數(shù)

結(jié)構(gòu)體定義

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 */
};
  • epoll_event中events變量為事件發(fā)生的類型胎源,可以是下面提到的事件類型EPOLLIN,EPOLLOUT,EPOLLHDUP,EPOLLPRI,EPOLLERR,EPOLLHUP,EPOLLET,EPOLLONESHOT,EPOLLWAKEUP中的一種棉钧,具體的參見(jiàn)下面的事件類型說(shuō)明。
  • data為一個(gè)聯(lián)合體涕蚤,可以根據(jù)不同的事件宪卿,來(lái)表示用戶數(shù)據(jù)內(nèi)容。例如可以是一個(gè)文件描述符万栅。

2.2.2 fd參數(shù)

fd為需要監(jiān)控的文件描述符佑钾。在這里是根據(jù)這個(gè)文件描述符對(duì)后面的event結(jié)構(gòu)進(jìn)行操作的。具體見(jiàn)下面的op參數(shù).

2.2.3 op參數(shù)

  • EPOLL_CTL_ADD:將文件描述符fd關(guān)聯(lián)到event結(jié)構(gòu)當(dāng)中,并把event事件添加到epfd實(shí)例當(dāng)中烦粒。相當(dāng)于把fd注冊(cè)到epoll實(shí)例當(dāng)中休溶。
  • EPOLL_CTL_MOD:根據(jù)文件描述符fd,來(lái)找到fd在epoll實(shí)例當(dāng)中對(duì)應(yīng)的event結(jié)構(gòu),修改這個(gè)event結(jié)構(gòu)扰她。
  • EPOLL_CTL_DEL:根據(jù)文件描述符fd兽掰,找到其所對(duì)應(yīng)的文件event結(jié)構(gòu),刪除這個(gè)fd上面的事件監(jiān)控徒役。
  • 總結(jié)下孽尽,epoll實(shí)際是通過(guò)fd來(lái)構(gòu)建一個(gè)event事件,通過(guò)這個(gè)event結(jié)構(gòu)來(lái)監(jiān)控fd上面發(fā)生的文件事件操作忧勿。

2.2.4 epdf參數(shù)

epfd為epoll_create 或者epoll_create1函數(shù)調(diào)用的返回值杉女,實(shí)際為一個(gè)文件描述符,指向epoll實(shí)例鸳吸。epoll系統(tǒng)操作都是通過(guò)這個(gè)文件描述符來(lái)進(jìn)行的熏挎。

2.3返回值

  • 調(diào)用成功返回0
  • 失敗返回-1,并置error錯(cuò)誤信息层释。

3 epoll_wait調(diào)用

3.1函數(shù)原型

#include <sys/epoll.h>
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);

3.2參數(shù)說(shuō)明

3.2.1 timeout參數(shù)

  • timeout參數(shù)指定了在沒(méi)有事件發(fā)生的時(shí)候epoll_wait調(diào)用阻塞的毫秒數(shù)(milliseconds)婆瓜。
  • 如果把這個(gè)值設(shè)置為-1,那么在沒(méi)有事件發(fā)生時(shí),這個(gè)調(diào)用會(huì)永遠(yuǎn)的阻塞下去廉白。
  • 如果timeout=0那么epoll_wait會(huì)檢查監(jiān)控的事件是否發(fā)生个初,然后立刻返回。
  • 上面指的事件猴蹂,可以包含監(jiān)控的文件事件院溺,也可以是信號(hào)中斷事件。

3.2.2 maxevent參數(shù)

  • maxevent,是一次調(diào)用epoll_wait可以返回有監(jiān)控事件發(fā)生的最大個(gè)數(shù)磅轻。
  • 例如監(jiān)控的事件中在某一時(shí)刻可能有20個(gè)發(fā)生了珍逸,但是如果這個(gè)時(shí)候maxevent=10,那么只會(huì)返回10個(gè)發(fā)生的事件。

3.2.3 events參數(shù)

  • events表示的是一個(gè)struct epoll_event數(shù)組聋溜,存放的是某個(gè)時(shí)刻發(fā)生事件的結(jié)構(gòu)體
  • 可以在epoll_wait調(diào)用結(jié)束之后谆膳,來(lái)訪問(wèn)這個(gè)結(jié)構(gòu)體里面的內(nèi)容例如fd來(lái)處理發(fā)生的文件事件。

3.2.4 epfd參數(shù)

  • epfd為epoll_create函數(shù)返回的文件描述符撮躁。epoll實(shí)例漱病。

3.3返回值

  • 沒(méi)有任何事件發(fā)生,或者超時(shí)返回0把曼。
  • 出現(xiàn)錯(cuò)誤返回-1杨帽,并設(shè)置error錯(cuò)誤信息。
  • 返回監(jiān)控事件發(fā)生的個(gè)數(shù)嗤军。

4.使用方法

下面是一個(gè)處理多個(gè)客戶端連接的服務(wù)端程序,可以根據(jù)這個(gè)大體的框架和自己的情況進(jìn)行修改注盈。

#include<stdio.h>
#include<unistd.h>
#include<sys/epoll.h>
#define MAX_EVENTS 10
int main (int argc,char* argv[] ) {
    struct epoll_event ev, events[MAX_EVENTS];
    int listen_sock, conn_sock, nfds, epollfd;

    /* Code to set up listening socket, 'listen_sock',
       (socket(), bind(), listen()) omitted */
    /*創(chuàng)建epoll實(shí)例*/
    epollfd = epoll_create1(0);
    if (epollfd == -1) {
        perror("epoll_create1");
        exit(EXIT_FAILURE);
    }

    /*設(shè)置epoll_event,關(guān)聯(lián)到epoll實(shí)例*/
    ev.events = EPOLLIN;
    ev.data.fd = listen_sock;
    /*注冊(cè)listen_sock到epoll實(shí)例*/
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
        perror("epoll_ctl: listen_sock");
        exit(EXIT_FAILURE);
    }
    for (;;) {
        /*監(jiān)控事件的發(fā)生,-1表示檢查監(jiān)控的事件后立即返回*/
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            perror("epoll_wait");
            exit(EXIT_FAILURE);
        }
        
        /*遍歷返回的事件叙赚,對(duì)事件進(jìn)行處理*/
        for (n = 0; n < nfds; ++n) {
            /*如果是發(fā)生在接收連接的套接字上老客,那么接受客戶端連接,并監(jiān)控新建的連接文件事件*/
            if (events[n].data.fd == listen_sock) {
                conn_sock = accept(listen_sock,
                        (struct sockaddr *) &local, &addrlen);
                if (conn_sock == -1) {
                    perror("accept");
                    exit(EXIT_FAILURE);
                }
                setnonblocking(conn_sock);
                /*設(shè)置新連接文件事件為讀寫事件*/
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = conn_sock;
                /*添加到epoll實(shí)例中纠俭,進(jìn)行監(jiān)控*/
                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                            &ev) == -1) {
                    perror("epoll_ctl: conn_sock");
                    exit(EXIT_FAILURE);
                }
            }/*如果發(fā)生的事件不是在接收連接的套接字上面*/ 
            else {
                /*處理產(chǎn)生的新的連接的數(shù)據(jù)沿量,例如,讀取客戶端寫的數(shù)據(jù)冤荆,或者向客戶端寫數(shù)據(jù)*/
                do_use_fd(events[n].data.fd);
            }
        }
    }
}

4.參考內(nèi)容

  • Linux man epoll_create
  • Linux man epoll_ctl
  • Linux man epoll_wait
  • Unix 網(wǎng)絡(luò)編程 卷I 套接字聯(lián)網(wǎng)API
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末朴则,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钓简,更是在濱河造成了極大的恐慌乌妒,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件外邓,死亡現(xiàn)場(chǎng)離奇詭異撤蚊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)损话,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門侦啸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)槽唾,“玉大人,你說(shuō)我怎么就攤上這事光涂∨悠迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵忘闻,是天一觀的道長(zhǎng)钝计。 經(jīng)常有香客問(wèn)我,道長(zhǎng)齐佳,這世上最難降的妖魔是什么私恬? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮炼吴,結(jié)果婚禮上本鸣,老公的妹妹穿的比我還像新娘。我一直安慰自己缺厉,他們只是感情好永高,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著提针,像睡著了一般。 火紅的嫁衣襯著肌膚如雪曹傀。 梳的紋絲不亂的頭發(fā)上辐脖,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音皆愉,去河邊找鬼嗜价。 笑死,一個(gè)胖子當(dāng)著我的面吹牛幕庐,可吹牛的內(nèi)容都是我干的久锥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼异剥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瑟由!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起冤寿,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤歹苦,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后督怜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殴瘦,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年号杠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蚪腋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丰歌。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屉凯,靈堂內(nèi)的尸體忽然破棺而出立帖,到底是詐尸還是另有隱情,我是刑警寧澤神得,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布厘惦,位于F島的核電站,受9級(jí)特大地震影響哩簿,放射性物質(zhì)發(fā)生泄漏宵蕉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一节榜、第九天 我趴在偏房一處隱蔽的房頂上張望羡玛。 院中可真熱鬧,春花似錦宗苍、人聲如沸稼稿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)让歼。三九已至,卻和暖如春丽啡,著一層夾襖步出監(jiān)牢的瞬間谋右,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工补箍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留改执,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓坑雅,卻偏偏與公主長(zhǎng)得像辈挂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子裹粤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容