gpt4 book ai didi

c - fgetc 在轮询管道后仍然阻塞

转载 作者:行者123 更新时间:2023-11-30 16:40:57 26 4
gpt4 key购买 nike

目前,我正在读取 execlp 的子程序的输入行。所以基本上,如果子程序无法正确执行,它在读取时不应该是管道信息,并且会抛出错误。

我尝试轮询文件描述符,无论程序是否正确执行,它都会返回一个。所以基本上我通过了 poll,然后 fgetc 挂起/阻塞,因为没有什么可读的,但 fgetc 也没有返回 -1。

阅读和投票:

char* read_line(int fd) {
// fd is a pipe's read end. I know it reads properly.
FILE *file = fdopen(fd, "r");
int ret;
struct pollfd fdinfo[1];
fdinfo[0].fd = fd;
fdinfo[0].events = POLLIN;
ret = poll(fdinfo,1, 1000);
if (ret < 0) {
return "NOPE";
}
char* result = malloc(sizeof(char) * 80);
memset(result, 0, sizeof(int));
int position = 0;
int next = 0;
while (1) {
next = fgetc(file); //STALLING HERE
if (next == '!') {
free(result);
return "!";
}
if (next == EOF || next == '\n') {
result[position] = '\0';
return result;
} else {
result[position++] = (char)next;
}
}
}

最佳答案

您没有充分检查 poll() 向您提供的信息。您确实可以通过返回 -1 来检测 poll() 报告错误的情况,但否则并不能保证有任何数据可供读取。负返回值表示 poll() 未能完成其工作;它不会告诉您任何轮询文件描述符的状态。

首先,如果超时,poll() 将返回 0。在这种情况下,您的代码只是向前滚动并尝试从文件描述符中读取,这将阻塞,除非数据恰好在 poll() 返回和调用 fgetc( )

其次,poll() 通过设置一个或多个相应的 revent 位来指示指定文件描述符的问题,并报告该 FD 上的事件(部分通过返回正数)。具体来说,

poll() sets the POLLHUP, POLLERR and POLLNVAL flag in revents if the condition is true, even if the application did not set the corresponding bit in events

A positive [return] value indicates the total number of pollfd structures [...] for which the revents member is non-zero

(POSIX 1003.1-2008;已添加强调)

如果向管道另一端写入的子进程崩溃,您很可能会看到 POLLHUP 事件。如果您的程序以某种方式搞砸了其文件描述符处理,您可能会看到 POLLNVAL 事件,并且您始终必须考虑到 I/O 错误的可能性,该错误 poll() 会发出 POLLERR 信号事件。

因此,为了避免阻塞,您应该仅在 poll() 返回 1 并在文件上的事件中发出 POLLIN 信号时才尝试从管道读取数据。可以想象,您可能会看到它与 POLLERR 或 POLLHUP 一起出现。如果有 POLLERR,我建议中止,但是当管道的写入端在任何进程中不再打开时,预计会出现 POLLHUP,并且这不会使任何仍可读取的数据无效(这将导致由随附的 POLLIN 发出信号)。

关于c - fgetc 在轮询管道后仍然阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46459554/

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