如何解决C 管叉 fd 问题 - 简单的 xv6 乒乓问题
这里是 C 新手。我正在尝试在 xv6 中编写一个简单的程序,该程序使用管道、分叉和文件描述符。
int
main(int argc,char *argv[])
{
int p[2]; // file descriptors for pipe
char recv_buf[5];
pipe(p);
if (fork() == 0) { // child
read(p[0],recv_buf,5);
printf("%d: received %s\n",getpid(),recv_buf);
close(p[0]);
write(p[1],"pong",5);
close(p[1]);
} else { // parent
write(p[1],"ping",5);
close(p[1]);
read(p[0],recv_buf);
close(p[0]);
}
exit(0);
}
我以为程序会成功打印
$ ./pingpong
$ "3: received ping"
$ "4: received pong"
到终端输出。
相反,输出为:
$ ./pingpong
$ "3: received ping"
谁能解释一下这里发生了什么?我认为每个进程都有自己的文件描述符副本,读/写会挂起父进程,直到管道的另一端有输出。那么为什么子进程没有收到“pong”调用呢?
请注意,如果我在父级中添加一个 wait(0),问题就会消失。
int
main(int argc,5);
wait(0); // this fixes the problem. but why?
close(p[1]);
read(p[0],recv_buf);
close(p[0]);
}
exit(0);
}
$ ./pingpong
$ "3: received ping"
$ "4: received pong"
谁能解释为什么 wait(0) 会导致程序成功?
解决方法
实际上,我在输入此内容后不久就找到了答案。
带有第一个程序的程序是在父块内部写入输出文件描述符,然后立即从输入文件描述符读取,这意味着父进程没有挂起。
结果是父进程在子进程能够进行任何读/写之前退出。
if (fork() == 0) { // child process never reached
read(p[0],recv_buf,5);
printf("%d: received %s\n",getpid(),recv_buf);
close(p[0]);
write(p[1],"pong",5);
close(p[1]);
} else { // parent
write(p[1],"ping",5); // write to output fd
close(p[1]); // close output fd
read(p[0],5); // read "ping" from input fd
printf("%d: received %s\n",recv_buf); // print "ping"
close(p[0]); // close input fd
}
exit(0); // parent process exists immediately
wait(0) 通过允许子进程在父进程到达读取块之前读/写来解决这个问题
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。