假设我有这个示例代码(为了清楚起见,基本上省略了错误检查)
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}
。出于某种原因,尽管关闭了管道的父进程的写端,但似乎从未在fgetc
循环中到达 EOF ,就好像子进程正在等待更多输入一样。我忘记关闭一些文件描述符了吗?即使不使用文件指针(即原始 POSIX 读取和写入),它仍然挂起。
我看到一些类似的回答问题,所以这可能是重复的。
当我运行此代码时,我看到:
[notroot]$ ./c_way
I have 5 apples.
然后挂了。
这是一场竞赛:您的父进程在子进程 exec 的cat之前从管道读取自己刚刚写入的数据(并将其写入标准输出)。
孩子什么也没读——管道已经被父母排空了——因此耐心地阻塞在标准输入上等待输入。与此同时,父进程耐心地阻塞在管道的读取端,等待永远不会到达的输入。
您需要两个管道:一个将父级连接到子级标准输入,另一个将子级标准输出连接到父级。(另见socketpair。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句