gpt4 book ai didi

c - 以下情况如何避免read()挂起?

转载 作者:太空狗 更新时间:2023-10-29 12:09:12 26 4
gpt4 key购买 nike

我有一些代码可以 fork 一个第三方应用程序并将其标准输出重定向到父进程,大致如下(为简洁起见,这里没有错误处理):

char* args[] = {"/path/to/3rd/party/binary", "with", "args", NULL};

int fds[2];
pipe2(fds, O_CLOEXEC);

pid_t pid = fork();
if (pid == 0)
{
dup2(fds[1], STDOUT_FILENO);
execvp(args[0], args);
_exit(1);
}
else
{
close(fds[1]);

char buf[1024];
int bytes_read;
while ((bytes_read = read(fds[0], buf, sizeof buf - 1)) > 0)
{
buf[bytes_read] = '\0';
printf("%s", buf);
}

close(fds[0]);
waitpid(pid, NULL, 0);
}

我没有第三方应用程序的代码,它是专有的二进制文件。当使用与上述代码中使用的参数相同的参数在终端中运行第三方应用程序时,它最终会完成。但是,当使用上面的代码fork第三方二进制文件时,它并没有完成,而是变成了一个僵尸进程,上面的代码卡在了read()调用上。

fork 的第三方二进制文件本身 fork 了两个守护进程(同样,我不控制专有二进制文件),我认为这是导致问题的原因。 fork 的守护进程将拥有复制文件描述符的副本,从而阻止 read() 完成。实际上,如果 dup2() 调用被替换为:

dup3(fds[1], STDOUT_FILENO, O_CLOEXEC);

子进程完成,但当然没有输出重定向到父进程。此外,当上面的代码被修改为不通过管道将任何输出重定向到父进程时,子进程会正确完成。

在这种情况下是否有可能以某种方式防止 read() 调用挂起,或者我是否需要求助于某种形式的非阻塞 I/O?

更新;使用简单的 popen() 会遇到同样的问题。

(后续来自:read() hangs on zombie process)

最佳答案

您需要特别忽略 SIGCHLD。收割僵尸是你的责任,但在 read 中被阻塞时你无法收割。如果在吞下 SIGCHLD 后调用 read,您将永远处于 read 状态。

关于c - 以下情况如何避免read()挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53562111/

26 4 0
文章推荐: linux - 在 github 上使用 cmake 进行共享库版本控制
文章推荐: javascript - html 标签中的angularjs表达式