【发布时间】:2018-09-09 18:30:58
【问题描述】:
我必须创建 2 个子进程并将数据从父进程发送到这两个进程,所以我使用了pipe。
如果我只使用 1 个子进程和 1 个管道,那么与 fdopen、fscanf 和 fprintf 完美配合。
另外,如果我创建 2 个管道并将数据发送到单个进程,仍然可以正常工作。
但是,如果我创建第二个进程并尝试从第二个pipe 读取,则什么也不会发生。
例如:
int main() {
pid_t pid1, pid2;
int a[2];
pipe(a);
pid1 = fork();
if(pid1 == 0) {
char x,y;
FILE *stream;
stream = fdopen(a[0],"r");
fscanf(stream,"%c",&x);
printf("%c\n", x);
close(a[1]);
close(a[0]);
} else {
int b[2];
pipe(b);
pid2 = fork();
FILE *stream1, *stream2;
close(a[0]);
close(b[0]);
stream1 = fdopen(a[1],"w");
stream2 = fdopen(b[1],"w");
fprintf(stream1, "yo bella zio\n");
fprintf(stream2, "como estas\n");
fflush(stream1);
fflush(stream2);
close(a[1]);
close(b[1]);
waitpid (pid1, NULL, 0);
waitpid (pid2, NULL, 0);
if (pid2 == 0) {
FILE *stream;
close(b[1]);
close(a[1]);
close(a[0]);
stream = fdopen(b[0],"r");
fscanf(stream,"%c",&x);
printf("%c\n", x);
} else {
}
}
}
我真的尝试了所有组合。一起声明所有管道,关闭或不关闭管道。什么都没有。
【问题讨论】:
-
第二个
fork()之后的很多工作只能由原始(父)进程完成。您应该更快地分离第二个子进程的工作。请特别注意,您在执行fdopen()调用之前关闭了b[0];你稍后再尝试fdopen(b[0], "r"),但为时已晚。将if (pid2 == 0)块向上移动到第二个fork()之后。可能仍然存在问题,但它们与您当前的问题不同。这说明了为什么检查系统调用是否成功是个好主意。如果你检查最后一个fdopen(),你就会知道它失败了。 -
请注意,您的声明 '我真的尝试了所有组合......但没有任何[有效]' 是夸大其词 - 你可以合理地说 '我真的尝试了很多组合......但[我试过]没有任何工作'。那将是准确的。您没有尝试所有组合,因为其中至少有一种会奏效。