gpt4 book ai didi

linux - 其他进程关闭fifo时无法从epoll_wait中唤醒

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:11:14 25 4
gpt4 key购买 nike

我在两个不同的二进制文件中看到了不同的 epollselect 行为,希望得到一些调试帮助。下面将交替使用epoll_waitselect

我有两个进程,一个写入者和一个读取者,它们通过先进先出进行通信。读取器执行 epoll_wait 以收到写入通知。我还想知道作者什么时候关闭 fifo,看来 epoll_wait 也应该通知我这件事。以下玩具程序的行为符合预期,说明了我正在努力完成的工作:

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <unistd.h>

int
main(int argc, char** argv)
{
const char* filename = "tempfile";
char buf[1024];
memset(buf, 0, sizeof(buf));

struct stat statbuf;
if (!stat(filename, &statbuf))
unlink(filename);

mkfifo(filename, S_IRUSR | S_IWUSR);

pid_t pid = fork();
if (!pid) {
int fd = open(filename, O_WRONLY);
printf("Opened %d for writing\n", fd);
sleep(3);
close(fd);
} else {
int fd = open(filename, O_RDONLY);
printf("Opened %d for reading\n", fd);

static const int MAX_LENGTH = 1;
struct epoll_event init;
struct epoll_event evs[MAX_LENGTH];
int efd = epoll_create(MAX_LENGTH);

int i;
for (i = 0; i < MAX_LENGTH; ++i) {
init.data.u64 = 0;
init.data.fd = fd;
init.events |= EPOLLIN | EPOLLPRI | EPOLLHUP;
epoll_ctl(efd, EPOLL_CTL_ADD, fd, &init);
}

while (1) {
int nfds = epoll_wait(efd, evs, MAX_LENGTH, -1);
printf("%d fds ready\n", nfds);
int nread = read(fd, buf, sizeof(buf));
if (nread < 0) {
perror("read");
exit(1);
} else if (!nread) {
printf("Child %d closed the pipe\n", pid);
break;
}
printf("Reading: %s\n", buf);
}
}
return 0;
}

但是,当我与另一个阅读器(我无权发布其代码,但它进行完全相同的调用——玩具程序以其为模型)执行此操作时,进程不会在编写器关闭时唤醒先进先出。玩具阅读器还使用 select 给出了所需的语义。配置为使用 select 的真实阅读器也会失败。

是什么导致了两者的不同行为?对于任何提供的假设,我如何验证它们?我正在运行 Linux 2.6.38.8。

最佳答案

strace是确认系统调用被正确调用(即参数被正确传递并且它们不会返回任何意外错误)的好工具。

除此之外,我建议使用 lsof检查是否没有其他进程仍然打开 FIFO。

关于linux - 其他进程关闭fifo时无法从epoll_wait中唤醒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13089632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com