>假设我有这个示例代码(为了清楚起见,基本上省略了错误检查(
static void c_way() {
int pipefd[2], ch;
FILE *rf, *wf;
pipe(pipefd);
switch (fork()) {
case -1:
/* something went wrong */
break;
case 0:
dup2(pipefd[0], STDIN_FILENO);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[0]);
close(pipefd[1]);
execvp(cat_args[0], cat_args);
_exit(0);
}
rf = fdopen(pipefd[0], "r");
wf = fdopen(pipefd[1], "w");
fprintf(wf, "I have %d apples.n", 5);
fclose(wf);
while ((ch = fgetc(rf)) != EOF)
putchar(ch);
puts("Done reading.");
fflush(stdout);
fclose(rf);
}
cat_args
只是{"cat", "-", NULL}
.出于某种原因,尽管已经关闭了管道的父进程的写入端,但 EOF 似乎从未在fgetc
循环中到达,就好像子进程正在等待更多输入一样。我忘了关闭一些文件描述符吗?即使不使用文件指针(即 POSIX 读取和写入.raw它仍然挂起。
我看到一些类似的回答问题,所以这可能是重复的。
当我运行这段代码时,我看到:
[notroot]$ ./c_way
I have 5 apples.
然后是挂。
这是一场比赛:你的父进程在子进程exec的cat之前从管道中读取自己刚刚写入的数据(并将其写入stdout(。
孩子什么也没读——管道已经被父母排干了——因此耐心地阻止了等待输入的 stdin。 与此同时,父级耐心地阻止管道的读取端,等待永远不会到达的输入。
您需要两个管道:一个用于将父级连接到子标准输出,另一个用于将子标准输出连接到父级。 (另请参阅套接字对。