epoll_wait在闭合管道读取端的预期行为是什么?

时间:2013-11-09 02:05:50

标签: c linux epoll

我无法从epoll文档中理解这一点:我说pipe(fd)所以我们有fd[0]阅读和fd[1]写作。我们将一些内容写入fd[1]然后关闭它:

write(fd[1], "abc", 3);
write(fd[1], "def", 3);
close(fd[1]);

我们可能同时创建一个epoll实例,让它等到它可以从fd[0]读取,并在它读取后读取3个字节。

int epoll_fd = epoll_create(10);
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = fd[0];
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd[0], &ev);

struct epoll_event event;
epoll_wait(epoll_fd, &event, 1, -1);
char buffer[100];
read(fd[0], buffer, 3);

现在我们再次致电epoll_wait。即使管道关闭,内核仍然应该为我们缓冲3个字节,可以从fd[0]读取,是吗?所以我希望以下工作(即不阻止):

epoll_wait(epoll_fd, &event, 1, -1);
read(fd[0], buffer, 3);  // buffer should start with "def" now

现在管道中没有任何东西,写入结束了。如果我epoll_wait第三次会怎么样?

epoll_wait(epoll_fd, &event, 1, -1);  // will this block indefinitely?
read(fd[0], buffer, 3);

我有两个不同的代码,似乎在这里表示不同的答案,所以我想知道应该发生什么来更好地解读正在发生的事情。

2 个答案:

答案 0 :(得分:3)

正在关闭的管道的写入端应该用read()返回0来发出信号。

假设:

  • 您没有使用epoll edge trigger
  • 您已检查所有错误的来电。
  • 写结束真的是关闭的 (即,例如,没有泄露的描述符 dup()call或fork())

然后你的最后一个epoll_wait不应该阻塞,下面的read()应该返回0。

(并记得检查read()是否返回您认为返回的字节数)

答案 1 :(得分:0)

关于你的帖子的这一行:

epoll_wait(epoll_fd, &event, 1, -1);  // will this block indefinitely?  

maxevents 参数设置为1,因此您最多只能看到一个事件,但这与您的问题有关,真的。
超时 参数设置为-1,这会导致epoll_wait() 无限期阻止

如果您不希望它阻止或传递一些有限的时间,则传递0表示超时,这将导致epoll_wait()立即返回,即使没有事件。