poll(2) 是否保证可以处理重复的文件描述符?

Is poll(2) guaranteed to work with duplicated file descriptors?

我广泛使用 poll(2) 进行多路复用 I/O 这允许我每个线程有一个函数收集所有来自工作人员的填充 pollfd 条目,轮询他们和 return 将条目返回给工作人员进行处理。所有其他 IO 调用都是非阻塞的。

这确实很好用,但是随着我扩展工作人员,如果一些 pollfd 条目可以包含相同的文件描述符两次或更多次,可能具有相同的预期事件集,这将简化我的工作.但是我没有找到 poll 是否可以处理这个问题的任何保证或警告。

那么,poll 是否可以处理带有可能 same/different 事件集的重复文件描述符的条目?例如

struct pollfd entries[]={{fd,POLLIN,0},{fd,POLLOUT,0},{fd,POLLIN|POLLOUT,0}};
#include <poll.h>
#include <stdio.h>
#include <assert.h>

int main() {
    int fd = 0;
    struct pollfd entries[] = {
        {fd, POLLIN, 0}, {fd, POLLOUT, 0}, {fd, POLLIN | POLLOUT, 0}};

    if( /* FD is writeable */1)
    {
        // No errors for simplicty
        // POLLOUT not queried -> not filled.
        assert(entries[0].revents == 0);
        // POLLOUT queried -> filled.
        assert(entries[1].revents == POLLOUT);
        // POLLOUT queried again -> filled AGAIN. THIS MUST WORK
        assert(entries[2].revents == POLLOUT);
    }
    if( /* FD is readable */1)
    {
        // No errors for simplicty

        // POLLIN queried -> filled.
        assert(entries[0].revents == POLLIN);
        // POLLIN not queried -> not filled.
        assert(entries[1].revents == 0);
        // POLLIN queried again -> filled AGAIN. THIS MUST WORK.
        assert(entries[2].revents == POLLIN);
    }
}

我必须避免的情况是只有一些条目被 poll 填充,例如只有 entries[1]revents 中有 POLLOUT 但没有 entries[2].

epoll呢?

我认为这充其量是未指定的。如果您正在创建一个应用程序,您应该 而不是 取决于收到事件时的行为,所有 revents 都会设置它。

请注意,当 poll return 在 revent 中存在某些内容时,实际状态 可能 可能会在 之间发生变化 结束对 poll 的调用以及您对其他任何内容的调用。所以即使你有POLLIN,也可能没有什么可读的

Is poll(2) guaranteed to work with duplicated file descriptors?

当然可以。

If fd is writeable will all entries with POLLOUT in events have POLLOUT in revents?

If fd is readable, ... POLLIN...?

Will any errors on fd show on all entries with that fd?

保证至少有一个revents与事件一起设置

Will poll return the true number of active entries?

投票将return设置了多少。

Will poll itself not return any errors?

没有

What about epoll?

不是POSIX。我相信以上内容也算作 epoll,因为我没有在文档中找到任何保证。