0

我无法从 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);

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

4

2 回答 2

3

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

假设:

  • 您没有使用 epoll 边缘触发器
  • 您已检查所有调用是否有错误。
  • 写端确实是关闭的(即没有来自例如 dup() 调用或 fork() 的泄漏描述符)

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

(记住检查 read() 返回的字节数是你假设它返回的)

于 2013-11-09T02:26:52.793 回答
0

关于你帖子的这一行:

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

maxevents参数设置为,因此无论如何1您最多只能看到一个事件,但这与您的问题几乎没有关系,真的。timeout参数设置为
,这将导致无限期阻塞-1epoll_wait()

如果你不希望它阻塞,或者通过一些有限的时间,然后通过 0 表示超时,这将导致epoll_wait() 立即返回,即使没有事件。

于 2013-11-09T02:25:37.167 回答