2015-06-20 103 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 .. –