linux手册翻译——epoll_ctl(2)


epoll_ctl 一 epll 文件描述符的控制接口

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


此操作用于要在epoll的interest list中增、改、删entry(entry包括了fd和设定的事件),具体的操作由op参数指定:

  • EPOLL_CTL_ADD
    在epoll的interest list中新增一个entry。
  • EPOLL_CTL_ MOD
    修改interest list 中fd的event信息
  • EPOLL_CTL_DEL
    从interest list中删除一个entry

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 events */
        epoll_data_t data;        /* User data variable */
};

epoll_event的data成员指定内核应该保存的数据,并在epoll_wait准备好时返回,可用于标识触发event的fd是那个,这个很重要
epoll_event的events成员是位掩码,由以下0个或多个可用事件类型组合到一起:

  • EPOLLIN
    fd关联的文件可进行read()操作(不阻塞)。

  • EPOLLOUT
    fd关联的文件可进行write()操作(不阻塞)。

  • EPOLLRDHUP
    流套接字对(stream socket peer)关闭连接或关闭写入一半的连接(此标志用于编写简单代码以在ET模老下检测peer shutdown很有用)。

  • EPOLLPRI
    文件描述符存在异常性情况,详见poll(2)

  • EPOLLERR
    文件描述符发生错误。管道读取端关闭时,也会向写端报告此事件。epoll_wait会一直报告此事件;调用epoll_ctl时不需要设置。

  • EPOLLHUP
    文件描述符发生Hang up时。
    同样epoll_wait也会一直报告此事件,无需调用时设置。
    当从管道或流套接字等通道读取时,此事件仅指示关闭了end of the channel。只有等通道中所有未完成的数据都被消耗后,从通道中的后续读取才会返回0(文件末尾)。

  • EPOLLET
    使用边缘触发模式(ET),默认情况是LT模式。此标志是用于配置的,epoll_wait永不会返回此事件。

  • EPOLLNESHOT
    配置fd一次性通知,即在epoll_wait通知一次fd事件后,就将fd以在interest list中禁用,不再报告此fd的其他事件。用户必须使用EPoll_CTL_MOD重新配置。
    此事件也是永不返回。

  • EPOLLWAKEUP
    If EPOLLONESHOT and EPOLLET are clear and the process has the CAP_BLOCK_SUSPEND capability, ensure that the system does not enter "suspend" or "hibernate" while this event is pending or being processed. The event is considered as being "processed" from the time when it is returned by a call to epoll_wait(2) until the next call to epoll_wait(2) on the same epoll(7) file descriptor, the closure of that file descriptor, the removal of the event file descriptor with EPOLL_CTL_DEL, or the clearing of EPOLLWAKEUP for the event file descriptor with EPOLL_CTL_MOD. See also BUGS.
    This flag is an input flag for the event.events field when calling epoll_ctl(); it is never returned by epoll_wait(2).

  • EPOLLEXCLUSIVE
    Sets an exclusive wakeup mode for the epoll file descriptor that is being attached to the target file descriptor, fd. When a wakeup event occurs and multiple epoll file descriptors are attached to the same target file using EPOLLEXCLUSIVE, one or more of the epoll file descriptors will receive an event with epoll_wait(2). The default in this scenario (when EPOLLEXCLUSIVE is not set) is for all epoll file descriptors to receive an event. EPOLLEXCLUSIVE is thus useful for avoiding thundering herd problems in certain scenarios.
    If the same file descriptor is in multiple epoll instances, some with the EPOLLEXCLUSIVE flag, and others without, then events will be provided to all epoll instances that did not specify EPOLLEXCLUSIVE, and at least one of the epoll instances that did specify EPOLLEXCLUSIVE.
    The following values may be specified in conjunction with EPOLLEXCLUSIVE: EPOLLIN, EPOLLOUT, EPOLLWAKEUP, and EPOLLET. EPOLLHUP and EPOLLERR can also be specified, but this is not required: as usual, these events are always reported if they occur, regardless of whether they are specified in events. Attempts to specify other values in events yield the error EINVAL.
    EPOLLEXCLUSIVE may be used only in an EPOLL_CTL_ADD operation; attempts to employ it with EPOLL_CTL_MOD yield an error. If EPOLLEXCLUSIVE has been set using epoll_ctl(), then a subsequent EPOLL_CTL_MOD on the same epfd, fd pair yields an error. A call to epoll_ctl() that specifies EPOLLEXCLUSIVE in events and specifies the target file descriptor fd as an epoll instance will likewise fail. The error in all of these cases is EINVAL.
    The EPOLLEXCLUSIVE flag is an input flag for the event.events field when calling epoll_ctl(); it is never returned by epoll_wait(2).


成功时,epoll_ctl() 返回零。 发生错误时,epoll_ctl() 返回 -1 并设置 errno 以指示错误。

  • EBADF epfd or fd is not a valid file descriptor.
  • EEXIST op was EPOLL_CTL_ADD, and the supplied file descriptor fd is already registered with this epoll instance.
  • EINVAL epfd is not an epoll file descriptor, or fd is the same as epfd, or the requested operation op is not supported by this interface.
  • EINVAL An invalid event type was specified along with EPOLLEXCLUSIVE in events.
  • EINVAL op was EPOLL_CTL_MOD and events included EPOLLEXCLUSIVE.
  • EINVAL op was EPOLL_CTL_MOD and the EPOLLEXCLUSIVE flag has previously been applied to this epfd, fd pair.
  • EINVAL EPOLLEXCLUSIVE was specified in event and fd refers to an epoll instance.
  • ELOOP fd refers to an epoll instance and this EPOLL_CTL_ADD operation would result in a circular loop of epoll instances monitoring one another or a nesting depth of epoll instances greater than 5.
  • ENOENT op was EPOLL_CTL_MOD or EPOLL_CTL_DEL, and fd is not registered with this epoll instance.
  • ENOMEM There was insufficient memory to handle the requested op control operation.
  • ENOSPC The limit imposed by /proc/sys/fs/epoll/max_user_watches was encountered while trying to register (EPOLL_CTL_ADD) a new file descriptor on an epoll instance. See epoll(7) for further details.
  • EPERM The target file fd does not support epoll. This error can occur if fd refers to, for example, a regular file or a directory.


epoll_ctl() 在 2.6 版中被添加到内核中。 从版本 2.3.2 开始,glibc 中提供了库支持。


epoll_ctl() is Linux-specific.


The epoll interface supports all file descriptors that support poll(2).


In kernel versions before 2.6.9, the EPOLL_CTL_DEL operation required a non-null pointer in event, even though this argument is ignored. Since Linux 2.6.9, event can be specified as NULL when using EPOLL_CTL_DEL. Applications that need to be portable to kernels before 2.6.9 should specify a non-null pointer in event.

If EPOLLWAKEUP is specified in flags, but the caller does not have the CAP_BLOCK_SUSPEND capability, then the EPOLLWAKEUP flag is silently ignored. This unfortunate behavior is necessary because no validity checks were performed on the flags argument in the original implementation, and the addition of the EPOLLWAKEUP with a check that caused the call to fail if the caller did not have the CAP_BLOCK_SUSPEND capability caused a breakage in at least one existing user-space application that happened to randomly (and uselessly) specify this bit. A robust application should therefore double check that it has the CAP_BLOCK_SUSPEND capability if attempting to use the EPOLLWAKEUP flag.

你可能感兴趣的:(linux手册翻译——epoll_ctl(2))