• (转)浅析epoll – epoll函数深入讲解


    原文地址:http://www.cppfans.org/1418.html

    浅析epoll – epoll函数深入讲解

    前一篇大致讲了一下epoll是个什么东西,优点等内容,这篇延续上一篇的内容,主要是分析epoll的函数,epoll高性能的深入分析。

    epoll的三大函数

    1.创建epoll fd函数

    int epoll_create(int size);

    epoll_create()创建一个epoll的事例,通知内核需要监听size个fd。size指的并不是最大的后备存储设备,而是衡量内核内部结构大小的一个提示。当创建成功后,会占用一个fd,所以记得在使用完之后调用close(),否则fd可能会被耗尽。

    Note:自从Linux2.6.8版本以后,size值其实是没什么用的,不过要大于0,因为内核可以动态的分配大小,所以不需要size这个提示了。

    创建还有另外一个函数

    int epoll_create1(int flag);

    这个函数是在linux 2.6.27中加入的,当你在看陈硕的muduo时可以看到这个函数,其实它和epoll_create差不多,不同的是epoll_create1函数的参数是flag,当flag是0时,表示和epoll_create函数完全一样,不需要size的提示了。

    当flag = EPOLL_CLOEXEC,创建的epfd会设置FD_CLOEXEC

    当flag = EPOLL_NONBLOCK,创建的epfd会设置为非阻塞

    一般用法都是使用EPOLL_CLOEXEC.

    Note:关于FD_CLOEXEC,现在网上好多都说的有点问题,我翻阅了一些资料,请教了一些人,大约明白它的意思了。

    它是fd的一个标识说明,用来设置文件close-on-exec状态的。当close-on-exec状态为0时,调用exec时,fd不会被关闭;状态非零时则被关闭,这样做可以防止fd泄露给执行exec后的进程。关于exec的用法,大家可以去自己查阅下,或者直接man exec。

    2.epoll事件的注册函数

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

    select是在监听时告诉内核要监听的事件,而epoll_ctl是先注册需要监听的事件。

    第一个参数epfd,为epoll_create返回的的epoll fd。

    第二个参数op表示操作值。有三个操作类型,

    EPOLL_CTL_ADD // 注册目标fd到epfd中,同时关联内部event到fd上

    EPOLL_CTL_MOD // 修改已经注册到fd的监听事件

    EPOLL_CTL_DEL // 从epfd中删除/移除已注册的fd,event可以被忽略,也可以为NULL

    第三个参数fd表示需要监听的fd。

    第四个参数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 */
    };

    event参数是一个枚举的集合,可以用” | “来增加事件类型,枚举如下:

    EPOLLIN:表示关联的fd可以进行读操作了。
    EPOLLOUT:表示关联的fd可以进行写操作了。
    EPOLLRDHUP(since Linux 2.6.17):表示套接字关闭了连接,或者关闭了正写一半的连接。
    EPOLLPRI:表示关联的fd有紧急优先事件可以进行读操作了。
    EPOLLERR:表示关联的fd发生了错误,epoll_wait会一直等待这个事件,所以一般没必要设置这个属性。
    EPOLLHUP:表示关联的fd挂起了,epoll_wait会一直等待这个事件,所以一般没必要设置这个属性。
    EPOLLET:设置关联的fd为ET的工作方式,epoll的默认工作方式是LT。
    EPOLLONESHOT (since Linux 2.6.2):设置关联的fd为one-shot的工作方式。表示只监听一次事件,如果要再次监听,需要把socket放入到epoll队列中。

    3.epoll等待事件函数

    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);

    上面两个函数的参数含义:

    第一个参数:表示epoll_wait等待epfd上的事件

    第二个参数:events指针携带有epoll_data_t数据

    第三个参数:maxevents告诉内核events有多大,该值必须大于0

    第四个参数:timeout表示超时时间(单位:毫秒)

    epoll_pwait(since linux 2.6.19)允许一个应用程序安全的等待,直到fd设备准备就绪,或者捕获到一个信号量。其中sigmask表示要捕获的信号量。

    函数如果等待成功,则返回fd的数字;0表示等待fd超时,其他错误号请查看errno

    函数到这里就讲完了,下一篇会写一个例子给大家看下这些函数是如何使用的。

  • 相关阅读:
    css选择器的分类及优先级计算方法总结
    第四周实验总结&实验报告
    2019春季总结
    第七周课程总结&实验报告五
    第六周学习总结&java实验报告四
    第二周Java学习总结
    第九周课程总结&实验报告(七)
    第五周学习总结&实验报告三
    第三周课程总结及实验报告
    第八周课程总结&实验报告(六)
  • 原文地址:https://www.cnblogs.com/sheshiji/p/3586908.html
Copyright © 2020-2023  润新知