我无法从 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);
我有两段不同的代码似乎都在这里表示不同的答案,所以我想知道应该发生什么以更好地破译正在发生的事情。
最佳答案
正在关闭的管道的写端应该用返回 0 的 read() 发出信号。
假设:
- 你没有使用 epoll 边缘触发器
- 您已检查所有调用是否有错误。
- 写端真的关闭了 (即没有从例如 a 泄漏的描述符 dup() 调用或 fork())
那么你最后的 epoll_wait 应该不会阻塞,下面的 read() 应该返回 0。
(并且记得检查 read() 返回的字节数是您假设它返回的字节数)
关于c - epoll_wait-ing 在封闭管道的读取端的预期行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19871556/