Operating system 关于从多子进程读取数据的管道问题 pid_t kids[argc]; int childCount=argc-1; int-fd[2]; /*创建管道*/ 如果(管道(fd)=-1){ fprintf(标准“管道故障”); 返回1; 对于(i=0;i

Operating system 关于从多子进程读取数据的管道问题 pid_t kids[argc]; int childCount=argc-1; int-fd[2]; /*创建管道*/ 如果(管道(fd)=-1){ fprintf(标准“管道故障”); 返回1; 对于(i=0;i,operating-system,pipe,process-management,Operating System,Pipe,Process Management,以上是代码,简化了一点。 我想做的是等待任何子项完成并处理其数据,然后重复此操作,直到所有子项完成。 有人能告诉我如何将子代生成的数据通过管道传输到父代吗?您没有提到当前代码的问题所在,并且您显示的代码没有编译,因此我只能猜测这是您真实代码的近似值 然而,以下是我注意到的: 在循环之前,您从未关闭if(pipe(fd)==-1)的主体,这意味着循环是if主体的一部分。这可能不是您想要的,尽管我不确定这是否是打字/复制粘贴错误。也许在真实代码中,您确实关闭了if 父进程的代码错误:因为它在for循

以上是代码,简化了一点。
我想做的是等待任何子项完成并处理其数据,然后重复此操作,直到所有子项完成。

有人能告诉我如何将子代生成的数据通过管道传输到父代吗?

您没有提到当前代码的问题所在,并且您显示的代码没有编译,因此我只能猜测这是您真实代码的近似值

然而,以下是我注意到的:

在循环之前,您从未关闭
if(pipe(fd)==-1)
的主体,这意味着循环是
if
主体的一部分。这可能不是您想要的,尽管我不确定这是否是打字/复制粘贴错误。也许在真实代码中,您确实关闭了
if

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

要修复此问题,必须确保父级在每个子级完成之前不会关闭管道。不要在循环内的父级中
close(2)
;而是在循环后执行此操作:

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]);
   }
}
for(i=0;i
由于您等待每个子级在循环中终止,因此可以保证在仍有活动写入程序时不会关闭管道

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]);