epoll 使用详解--epoll_ctl

添加套接字:

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

 参数详解:

  epfd:就是指定epoll文件描述符。

  op : 需要执行的操作,添加,修改,删除,详细如下。

    EPOLL_CTL_ADD
      在epoll的监视列表中添加一个文件描述符(即参数fd),指定监视的事件类型(参数event)。
    EPOLL_CTL_MOD
      修改监视列表中已经存在的描述符(即参数fd),修改其监视的事件类型(参数event)。
    EPOLL_CTL_DEL
      将某监视列表中已经存在的描述符(即参数fd)删除,参数event传NULL。

  fd:需要添加,修改,删除的套接字。
    event:需要epoll监视的时间类型。
        struct epoll_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 监视的事件类型 */
      epoll_data_t data; /* 用户数据 */
};

  struct epoll_event由两个成员组成,事件类型和用户数据。
  data:
  我们先说用户数据data,从上面代码可以看到,data是一个联合体类型,可以是指针,文件描述符,整形(机器字长)。这个数据传给epoll以后,epoll不会使用,只会在对应的事件触发后原样的返回给用户。实际开发中一般都是保存添加的套接字的描述符,用于当epoll事件返回时识别事件。如果有需要传其它值也可以,比如改成一个结构体或者对象的地址(可以避免一次使用套接字查找对象操作)。

  events:
  是一个事件集合,通过位掩码的方式表示不同的事件,可以同时设置多个,通过“|” 连接,可选项如下。
    EPOLLIN
      文件描述符是否可读。
    EPOLLOUT
      文件描述符是否可写。
    EPOLLRDHUP(Linux 2.6.17以后才能使用)
      对端关闭连接(被动),或者套接字处于半关闭状态(主动),这个事件会被触发。当使用边缘触发模式时,很方便写代码测试连接的对端是否关闭了连接。
      EPOLLPRI
      文件描述符是否异常
    EPOLLERR
      文件描述符是否错误。如果文件描述符已经关闭,继续写入也会收到这个事件。这个事件用户不设置也会被上报。
    EPOLLHUP
      套接字被挂起(所谓的被挂起是指??)。这个事件用户不设置也会被上报。
     EPOLLET
      设置epoll的触发模式为边缘触发模式。如果没有设置这个参数,epoll默认情况下是水平触发模式。详细可以参考后续的【epoll边缘触发与水平触发】。
      这是一个输入类型的参数,epoll_wait(2)不会返回这种事件。
    EPOLLONESHOT(Linux 2.6.2以后才支持)
      设置添加的事件只触发一次,当epoll_wait(2)报告一次事件后,这个文件描述符后续所有的事件都不会再报告。只是禁用,文件描述符还在监视队列中,用户可以通过epoll_ctl()的EPOLL_CTL_MOD重新添加事件。
      这是一个输入类型的参数,epoll_wait(2)不会返回这种事件。
      EPOLLWAKEUP (Linux 3.5以后才支持)
      xxxxx。
      这是一个输入类型的参数,epoll_wait(2)不会返回这种事件。
       EPOLLEXCLUSIVE (Linux 4.5以后才支持)
      xxxxx
      这是一个输入类型的参数,epoll_wait(2不会返回这种事件。

返回值:

  成功epoll_ctl()返回0。错误返回-1。错误码error会被设置。

错误码:
  EBADF :epfd或者fd不是一个有效的文件描述符。
  EEXIST :当参数是EPOLL_CTL_ADD时,当添加到fd已经在epfd中时,重复添加。
  EINVAL :
    1、当epfd不是一个文件描述符,或者fd是一个epfd,或者op是不支持的参数。
    2、设置了参数EPOLLEXCLUSIVE,却没有和其它有效的参数一起设置。
    3、使用参数EPOLL_CTL_MOD 时同时包含了EPOLLEXCLUSIVE
    4、使用参数EPOLL_CTL_MOD 时,当前epfd中的fd之前已经被设置了EPOLLEXCLUSIVE。
    5、EPOLLEXCLUSIVE ??????
  ELOOP :epoll监视队列是可以添加epoll描述符的,就是支持嵌套。当嵌套关系成环时,或者嵌套深度超过5层时,会报这个错误。
  ENOENT :使用EPOLL_CTL_MOD 和EPOLL_CTL_DEL添加 修改时,修改的套接字却不在epoll的监视队列中。
  ENOMEM :操作所需要的内存不够。
  ENOSPC :当EPOLL_CTL_ADD添加时,已经超过了epoll的规格限制。规格限制在:/proc/sys/fs/epoll/max_user_watches。
  EPERM :添加的fd不支持epoll。比如添加的是普通文件描述符。

BUGS:
  1、在Linux内核版本2.6.9之前,EPOLL_CTL_DEL操作时,event必须是一个非空的指针,实际并没有使用。2.6.9内核版本以后可以直接设置为NULL。

posted @ 2022-03-30 10:15  核心已转储  阅读(4389)  评论(0编辑  收藏  举报