为什么 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.
为什么这项技术对 select
和 poll
有效却对 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
相同的文件描述。考虑两种情况:
您没有做任何特别的事情,所以您的 dup2
最终关闭了与 non_writable_fd
关联的打开文件描述。在这种情况下 epoll
只是将其从集合中删除,那就是
您之前 dup
已经 non_writable_fd
进入了其他东西。在这种情况下,dup2
只是切断了 non_writable_fd
与其 OFD 之间的关联,OFD 继续存在,由 epoll
监视
在这两种情况下,您的 dup
调用都没有达到您想要的效果:您需要再次明确调用 epoll_ctl
。
假设我将不可写的 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.
为什么这项技术对 select
和 poll
有效却对 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
相同的文件描述。考虑两种情况:
您没有做任何特别的事情,所以您的
dup2
最终关闭了与non_writable_fd
关联的打开文件描述。在这种情况下epoll
只是将其从集合中删除,那就是您之前
dup
已经non_writable_fd
进入了其他东西。在这种情况下,dup2
只是切断了non_writable_fd
与其 OFD 之间的关联,OFD 继续存在,由epoll
监视
在这两种情况下,您的 dup
调用都没有达到您想要的效果:您需要再次明确调用 epoll_ctl
。