在一段时间内(1)我正在尝试:
使用fork()生成子进程;
重定向子进程标准输出,以便父进程可以看到它
从父进程在终端中打印结果
重复
奇怪的是,子进程的输出似乎被打印了两次
// parentToChild and childToParent are the pipes I'm using
while(1) {
int pid = fork();
if(pid < 0) {
// error, get out
exit(0);
} else if(pid != 0) {
// parent process
close(parentToChild[0]); // don't need read end of parentToChild
close(childToParent[1]); // don't need write end of childToParent
sleep(4);
char respBuffer[400];
int respBufferLength = read(childToParent[0], respBuffer, sizeof(respBuffer));
printf("before\n");
printf("parent tried to read something from its child and got: %s\n", respBuffer);
printf("after\n");
} else if (pid == 0) {
if(dup2(childToParent[1], STDOUT_FILENO) < 0) {
// printf("dup2 error");
};
close(childToParent[1]);
close(childToParent[0]);
close(parentToChild[1]); // write end of parentToChild not used
printf("child message");
// if we don't exit here, we run the risk of repeatedly creating more processes in a loop
exit(0);
}
}
我希望每次迭代时以下循环的输出为:
before
parent tried to read something from its child and got: child message
after
但是,每次迭代我都会得到:
before
parent tried to read something from its child and got: child message
after
child message
第二次打印“子消息”的原因是什么?
在调用fork()之前刷新stdout缓冲区似乎无法解决问题
有趣的是,删除while循环并保持其他所有内容不变
答案 0 :(得分:1)
在循环的第一次迭代中,您关闭了父级中的childToParent[1]
,并且没有重新创建管道,因此在循环的第二次迭代中,它试图重用那些封闭的管道,因此子级的dup2
调用失败,因此其printf转到终端。同时,在父级中,read
调用返回0而不向缓冲区写入任何内容,因此您只打印旧内容。