【发布时间】:2021-07-31 12:05:28
【问题描述】:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main() {
int p[2];
pipe(p);
if (fork() == 0) {
// child
/*#0*/ close(p[1]);
int received = -1;
while (read(p[0], &received, 4) != 0) {
printf("receive integer: %d\n", received);
received = -1;
}
printf("child exit\n");
exit(0);
} else {
// parent
/*#1*/ close(p[0]);
int sent = 42;
write(p[1], &sent, 4);
/*#2*/ close(p[1]);
printf("wait for child\n");
wait(0);
}
printf("finished\n");
}
我试图理解 C 中的 fork 和 pipe。这个程序派生了一个子进程,它从父进程接收一个整数,然后在管道关闭时退出。执行时,它会打印
wait for child
receive integer: 42
child exit
finished
然而,在close(p[1]); 的位置#0 被移除后,while 循环卡住了:read 将无限等待来自管道的传入变量并且永远不会检测到管道关闭。
有人可以向我解释为什么p[1] 必须由父(位置#2)和子(位置#0)进程关闭吗?
【问题讨论】:
-
因为它是这样工作的。在关闭管道之前,需要关闭管道的所有写入端。系统不会为您检测这种竞争条件;如果您自己被阻止,这是您需要修复的错误。
-
顺便说一句,您应该将
4替换为sizeof sent或sizeof received或sizeof(int)(最好是前两个)。