c - epoll_wait-ing 在封闭管道的读取端的预期行为是什么?

标签 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);

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

最佳答案

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

假设:

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

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

(并且记得检查 read() 返回的字节数是您假设它返回的字节数)

关于c - epoll_wait-ing 在封闭管道的读取端的预期行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19871556/

相关文章:

linux - Docker 将程序作为守护进程运行

c - 为什么 iconv 函数需要一个非常量输入缓冲区?

linux - Linux 内核中 slab 内存管理的缓存着色

c++ - 使用epoll_wait时如何正确读取数据

c - 如何在 C 中用新的字符数组覆盖字符数组(又名字符串)?

c++ - ld : foo. o :foo. h :6 multiple definition of `bar' foo. h:6: 首先在这里定义

c - 一个 nginx worker 进程是同时处理两个请求还是一个一个处理?

C++ 异步主机名解析

c++ - 将数据从 C 进程传递到 C++ 进程

c - 动态分配和_freeing_二维双数组