2015-06-20 69 views
0
pid_t kids[argc]; 
int childCount = argc - 1; 
int fd[2]; 
/* create the pipe*/ 
if (pipe(fd) == -1) { 
    fprintf(stderr ,"Pipe failed"); 
    return 1; 
for(i=0; i < childCount; i++) { 
    kids[i] = fork(); 
    if(kids[i] < 0){ 
     //fork fail 
    } 
    else if(kids[i] == 0) { 
    /* child process */ 
     sum = max + min;//sum and dif are results from each child process 
     dif = max - min; 
     /* close the unused end of pipe, in this case, the read end */ 
     close(fd[READ_END]); 
     /* write to the pipe */ 
     write(fd[WRITE_END], &sum, sizeof(sum)); 
     write(fd[WRITE_END], &dif, sizeof(dif)); 
     /* close write end */ 
     close(fd[WRITE_END]); 
     exit(0); 
    } 
    else { 
     waitpid(kids[i], &status, 0); 
     close(fd[WRITE_END]); 

     read(fd[READ_END], &sum, sizeof(float)); 
     read(fd[READ_END], &dif, sizeof(float)); 
     close(fd[READ_END]); 
    } 
} 

上面是代码,它被简化了一点。
我想要做的是等待任何孩子完成并处理其数据,然后重复此操作,直到所有的孩子都完成了。
有人可以告诉我如何将孩子生成的数据传给父母吗?
关于从多子进程读取数据的管道问题

回答

0

你没有提到你当前代码的问题是什么,你显示的代码没有编译,所以我只能猜测这是你的真实代码的近似值。

尽管如此,这里是吸引我的眼球:

你永远不循环,这意味着循环是if身体的一部分之前关闭的if (pipe(fd) == -1)身体。这可能不是你想要的,但我不确定它是否是拼写错误/复制粘贴错误。也许在真正的代码中,您确实关闭了if

父进程的代码是错误的:因为它在for循环内运行,所以您在管道的写和读端重复调用close(2)。这将导致close(2)返回一个错误(EBADF),在循环的第二次迭代时,您会公然忽略这个错误。同样在第二次迭代中,分叉的子将尝试关闭不再存在的管道的读取通道(因为我们刚刚分叉的父进程在再次分叉之前关闭了前一次迭代中的两端),然后它尝试写入不存在的管道。

要解决这个问题,您必须确保父母在每个孩子都完成之前不会关闭管道。在循环内的父代中不要close(2);相反,这样做在循环之后:

for(i=0; i < childCount; i++) { 
    kids[i] = fork(); 
    if(kids[i] < 0){ 
     //fork fail 
    } 
    else if(kids[i] == 0) { 
    /* child process */ 
     sum = max + min;//sum and dif are results from each child process 
     dif = max - min; 
     /* close the unused end of pipe, in this case, the read end */ 
     close(fd[READ_END]); 
     /* write to the pipe */ 
     write(fd[WRITE_END], &sum, sizeof(sum)); 
     write(fd[WRITE_END], &dif, sizeof(dif)); 
     /* close write end */ 
     close(fd[WRITE_END]); 
     exit(0); 
    } 
    else { 
     waitpid(kids[i], &status, 0); 
     read(fd[READ_END], &sum, sizeof(float)); 
     read(fd[READ_END], &dif, sizeof(float)); 
    } 
} 

close(fd[READ_END]); 
close(fd[WRITE_END]); 

既然你等待每个孩子在终止循环,可以保证的是,当仍然有活跃的作家,你会不会关闭管道。

+0

是的,我在帖子后找到了它。无论如何thnx .. –