为什么 epoll_wait() 对 dup2(writable_fd, non_writable_fd) 没有反应?

Why epoll_wait() doesn't react on dup2(writable_fd, non_writable_fd)?

假设我将不可写的 fd 添加到 epoll watcher 以等待它何时变为可写。

epoll_ctl(epollfd, EPOLL_CTL_ADD, non_writable_fd, {EPOLLOUT})

non_writable_fd 仍然不可写并且 epoll_wait 将 return 0 ready fds

那我做这个

dup2(writable_fd, non_writable_fd)

其中 writable_fd 是一个可写的文件描述符。现在我期望 epoll_wait 会立即 return 1 fd。但不幸的是它仍然超时 0 fd returned.

为什么这项技术对 selectpoll 有效却对 epoll 无效?

问题是 epoll 关心“打开文件描述”,而不是文件描述符。答案隐藏在几层手册页中。首先,epoll_wait:

Will closing a file descriptor cause it to be removed from all epoll sets automatically?

Yes, but be aware of the following point. A file descriptor is a reference to an open file description (see open(2))[...]

返回您的 dup2 通话:

dup2(writable_fd, non_writable_fd)

dup2 原子调用首先关闭 non_writable_fd,然后使其指向与 writable_fd 相同的文件描述。考虑两种情况:

  1. 您没有做任何特别的事情,所以您的 dup2 最终关闭了与 non_writable_fd 关联的打开文件描述。在这种情况下 epoll 只是将其从集合中删除,那就是

  2. 您之前 dup 已经 non_writable_fd 进入了其他东西。在这种情况下,dup2 只是切断了 non_writable_fd 与其 OFD 之间的关联,OFD 继续存在,由 epoll

  3. 监视

在这两种情况下,您的 dup 调用都没有达到您想要的效果:您需要再次明确调用 epoll_ctl