我有以下代码:
int fds[2];
if (pipe(fds) < 0) {
fprintf(stderr, "ERROR, unable to open pipe: %s\n", strerror(errno));
}
if (fcntl(fds[0], F_SETFL, O_NONBLOCK) < 0) {
fprintf(stderr, "ERROR, unable make read end non-blocking: %s\n", strerror(errno));
}
pid_t pid1 = fork();
if (pid1 == 0) {
if (close(fds[0]) < 0) {
fprintf(stderr, "ERROR, unable to close read end of pipe: %s\n", strerror(errno));
}
// go on to write something
}
pid_t pid2 = fork();
if (pid2 == 0) {
if (close(fds[1]) < 0) {
fprintf(stderr, "ERROR, unable to close write end of pipe: %s\n", strerror(errno));
}
// go on to read something
}
if (close(fds[1]) < 0) {
fprintf(stderr, "ERROR, unable to close write end of pipe in main process: %s\n", strerror(errno));
}
if (close(fds[0]) < 0) {
fprintf(stderr, "ERROR, unable to close read end of pipe in main process: %s\n", strerror(errno));
}
我收到错误消息“ERROR,无法在主进程中关闭管道的写入结尾:错误的文件描述符”。我的印象是你应该在任何不使用该目的的过程中关闭管道的每一端。主流程不使用此处的管道。它的存在只是为了让两个孩子进行交流。此外,对close()的任何其他调用都没有其他错误。我不明白为什么父进程不能只关闭管道的写端。
答案 0 :(得分:0)
我认为正在发生的事情是当子进程退出if语句时,它正在生成子进程并尝试隐藏已经关闭的管道:
pid_t pid1 = fork();
if (pid1 == 0) {
// child 1 comes here
if (close(fds[0]) < 0) {
fprintf(stderr, "ERROR, unable to close read end of pipe: %s\n", strerror(errno));
}
// go on to write something
// << you were supposed to call exit here. Child 1 passes through.
}
pid_t pid2 = fork();
if (pid2 == 0) {
// child 2 comes here first, but after that,
// child 1 will respawn a new child (child 3). Child 3
// closes a different pipe so no crash here.
if (close(fds[1]) < 0) {
fprintf(stderr, "ERROR, unable to close write end of pipe: %s\n", strerror(errno));
}
// go on to read something
// Big problem: Child 2 and Child 3 will pass through here.
}
// The main thread, as well as children 1, 2 and 3 are all here now.
// if any 2 threads try to close this pipe, you will get an error:
if (close(fds[1]) < 0) {
fprintf(stderr, "ERROR, unable to close write end of pipe in main process: %s\n", strerror(errno));
}
<强>解决方案强>
在if语句的末尾调用exit以防止子进程退出if语句并继续关闭管道。