我有这个程序。程序从stdin读取多个数字,同时按下ctrl + d(EOF)。正数用于子进程,负数用于其他子进程。我的问题是:为什么EOF不会通过管道发送到这两个进程? 这是我的计划:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
int p0top1[2],p0top2[2];
void tataWork()
{
int nr;
FILE *fout1, *fout2;
fout1 = fdopen(p0top1[1], "w");
fout2 = fdopen(p0top2[1], "w");
printf("Begin P0\n");
while(EOF != scanf("%d", &nr))
{
if(nr > 0)
{
fprintf(fout1,"%d\n", nr);
fflush(fout1);
}
else
{
fprintf(fout2,"%d\n", nr);
fflush(fout2);
}
}
close(p0top1[1]);
close(p0top2[1]);
printf("Finish P0\n");
}
void p1Work()
{
close(p0top1[1]);
printf("Begin P1\n");
int nr, i, n = 0, sum = 0, vector[1024];
FILE *fin;
fin = fdopen(p0top1[0], "r");
while(EOF != fscanf(fin, "%d", &nr))
{
vector[n++] = nr;
sum += nr;
}
for(i = 0; i < n; i++)
printf("%d ", vector[i]);
close(p0top1[0]);
printf("Finish P1\n");
}
void p2Work()
{
close(p0top2[1]);
printf("Begin P2\n");
int nr, i, n = 0, sum = 0, vector[1024];
FILE *fin;
fin = fdopen(p0top2[0], "r");
while(EOF != fscanf(fin, "%d", &nr))
{
vector[n++] = nr;
sum += nr;
}
printf("I am P2.\n");
for(i = 0; i < n; i++)
printf("%d ", vector[i]);
close(p0top2[0]);
printf("Finish P2\n");
}
void makePipe()
{
if(-1 == pipe(p0top1) )
{
perror("Error creating the pipe");
exit(1);
}
if(-1 == pipe(p0top2) )
{
perror("Error creating the pipe");
exit(1);
}
}
int main(void)
{
pid_t p1, p2;
makePipe();
if(-1 == (p1=fork()) )
{
perror("Error creating the child");
exit(3);
}
if(p1)
{
if(-1 == (p2=fork()) )
{
perror("Error creating the child");
exit(4);
}
if(p2)
{
tataWork();
}
else
{
p2Work();
}
}
else
{
p1Work();
}
return 0;
}
输出是这样的:
Begin P0
Begin P1
Begin P2
20 -3 4 -2
Finish P0
所以孩子们没有完成,因为EOF没有发送? 抱歉我的英语不好!!!
答案 0 :(得分:2)
当指向管道写入端的所有fd
都关闭时,将从管道中读取EOF。两个管道都有三个写入结束副本(一个在主进程中,一个在两个子进程中)。在你的程序中,你只关闭其中两个。在子进程中,您不会关闭实际上未被子进程使用的管道(但是,fork
仍然创建了一个副本)。
添加
close(p0top2[1]);
到p1work
和
close(p0top2[1]);
到p2Work
的开头,你的程序就可以了。