epoll相关

epoll 相关

标签(空格分隔): linux c/c++


1.epoll_create调用

int epoll_create(int size);
int epoll_create1(int flags);
  • 第一个函数epoll_create调用是比较常用的调用,第二个调用是改进版本。内核版本在2.9以及之后才能够使用。
  • 调用成功的返回值,是一个文件描述符(非负整数),指向一个epoll实例,这个文件描述符代表这后续对于epoll相关接口的引用。需要在使用结束后调用close关闭文件描述符。
  • 调用出现错误的返回值是-1,并可以在全局变量error中查看错误信息。
  • 第一个调用的参数size是,调用者在后续使用epoll添加感兴趣的文件描述符个数的大小,这个是一个给系统初次分配epoll监控文件描述符数据结构的内存空间的一个参考值,但是如果后来调用者,监听的事件超过这个范围,那么系统会额外的分配空间的。
    总的来说这个值只是操作系统的参考值。
  • epoll_create1参数是一个文件描述符标志,如果为0那么和 epoll_create(0)一样。

2 epoll_ctl调用

2.1函数原型

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

2.2参数说明

2.2.1 event参数

结构体定义

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变量为事件发生的类型,可以是下面提到的事件类型EPOLLIN,EPOLLOUT,EPOLLHDUP,EPOLLPRI,EPOLLERR,EPOLLHUP,EPOLLET,EPOLLONESHOT,EPOLLWAKEUP中的一种,具体的参见下面的事件类型说明。
  • data为一个联合体,可以根据不同的事件,来表示用户数据内容。例如可以是一个文件描述符。

2.2.2 fd参数

fd为需要监控的文件描述符。在这里是根据这个文件描述符对后面的event结构进行操作的。具体见下面的op参数.

2.2.3 op参数

  • EPOLL_CTL_ADD:将文件描述符fd关联到event结构当中,并把event事件添加到epfd实例当中。相当于把fd注册到epoll实例当中。
  • EPOLL_CTL_MOD:根据文件描述符fd,来找到fd在epoll实例当中对应的event结构,修改这个event结构。
  • EPOLL_CTL_DEL:根据文件描述符fd,找到其所对应的文件event结构,删除这个fd上面的事件监控。
  • 总结下,epoll实际是通过fd来构建一个event事件,通过这个event结构来监控fd上面发生的文件事件操作。

2.2.4 epdf参数

epfd为epoll_create 或者epoll_create1函数调用的返回值,实际为一个文件描述符,指向epoll实例。epoll系统操作都是通过这个文件描述符来进行的。

2.3返回值

  • 调用成功返回0
  • 失败返回-1,并置error错误信息。

3 epoll_wait调用

3.1函数原型

#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参数说明

3.2.1 timeout参数

  • timeout参数指定了在没有事件发生的时候epoll_wait调用阻塞的毫秒数(milliseconds)。
  • 如果把这个值设置为-1,那么在没有事件发生时,这个调用会永远的阻塞下去。
  • 如果timeout=0那么epoll_wait会检查监控的事件是否发生,然后立刻返回。
  • 上面指的事件,可以包含监控的文件事件,也可以是信号中断事件。

3.2.2 maxevent参数

  • maxevent,是一次调用epoll_wait可以返回有监控事件发生的最大个数。
  • 例如监控的事件中在某一时刻可能有20个发生了,但是如果这个时候maxevent=10,那么只会返回10个发生的事件。

3.2.3 events参数

  • events表示的是一个struct epoll_event数组,存放的是某个时刻发生事件的结构体
  • 可以在epoll_wait调用结束之后,来访问这个结构体里面的内容例如fd来处理发生的文件事件。

3.2.4 epfd参数

  • epfd为epoll_create函数返回的文件描述符。epoll实例。

3.3返回值

  • 没有任何事件发生,或者超时返回0。
  • 出现错误返回-1,并设置error错误信息。
  • 返回监控事件发生的个数。

4.使用方法

下面是一个处理多个客户端连接的服务端程序,可以根据这个大体的框架和自己的情况进行修改。

#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 */
    /*创建epoll实例*/
    epollfd = epoll_create1(0);
    if (epollfd == -1) {
        perror("epoll_create1");
        exit(EXIT_FAILURE);
    }

    /*设置epoll_event,关联到epoll实例*/
    ev.events = EPOLLIN;
    ev.data.fd = listen_sock;
    /*注册listen_sock到epoll实例*/
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
        perror("epoll_ctl: listen_sock");
        exit(EXIT_FAILURE);
    }
    for (;;) {
        /*监控事件的发生,-1表示检查监控的事件后立即返回*/
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            perror("epoll_wait");
            exit(EXIT_FAILURE);
        }
        
        /*遍历返回的事件,对事件进行处理*/
        for (n = 0; n < nfds; ++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);
                /*设置新连接文件事件为读写事件*/
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = conn_sock;
                /*添加到epoll实例中,进行监控*/
                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                            &ev) == -1) {
                    perror("epoll_ctl: conn_sock");
                    exit(EXIT_FAILURE);
                }
            }/*如果发生的事件不是在接收连接的套接字上面*/ 
            else {
                /*处理产生的新的连接的数据,例如,读取客户端写的数据,或者向客户端写数据*/
                do_use_fd(events[n].data.fd);
            }
        }
    }
}

4.参考内容

  • Linux man epoll_create
  • Linux man epoll_ctl
  • Linux man epoll_wait
  • Unix 网络编程 卷I 套接字联网API
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容