使用管道()从多个子进程中读取?

Posted

技术标签:

【中文标题】使用管道()从多个子进程中读取?【英文标题】:Reading from multiple child processes with pipe()? 【发布时间】:2021-10-13 07:52:15 【问题描述】:

我有一段代码,我试图在 N 个子进程中将问题拆分为 N 个子问题,让每个进程处理其给定的子问题,然后通过管道将结果合并在一起。

每个子问题的解决方案的大小是提前知道的,以 int 数组的形式。

问题似乎是主进程没有读入子问题解决方案。之后尝试访问读取的数据会给出NULL pointer error。我认为原因可能是由于在读入数据之前子进程退出,但我无法在自己的实验中验证这一点。

我使用的代码大致是这样的

  int** child_pipes = init_child_pipes(process_cnt);
  int* solution_sizes = get_solution_sizes(...);
  pid_t children[process_cnt];
  for (int i = 0; i < process_cnt; i++) 
    if ((children[i] = fork()) == 0) 
      // close all unused pipes for this child process
      for (int j = 1; j < process_cnt; j++) 
        close(child_pipes[j][0]); 
        if (i != j)
          close(child_pipes[j][1]);
      

      int* solution = do_subproblem(...)
      int c = write(child_pipes[i][1], solution, solution_sizes[i]);
      close(child_pipes[i][1]);
      exit(0); // exit so no loop
    
    else if (children[i] < 0)  // child < 0
      fprintf(stderr, "failed to create child processes");
      exit(1);
    
  

  // wait on children
  int status;
  for (int i = 0; i < process_cnt; i++) 
    waitpid(children[i], &status, 0);

  // merge cells
  int** all_subproblems = malloc(sizeof(int*) * process_cnt);
  for (int i = 0; i < process_cnt; i++) 
    close(child_pipes[i][1]); // close writing end
    read(child_pipes[i][0], &all_subproblems[i], solution_sizes[i]);
    close(child_pipes[i][0]); // close read end
  

我不确定我是否在这里错误地使用了fork()pipe(),但这肯定是问题所在。任何帮助将不胜感激!

【问题讨论】:

你没有为all_subproblems[i]分配内存。 为什么你所有的循环都是从1开始的?数组索引从 0 开始。 应该subproblem_sizessolution_sizes @Barmar 感谢您指出那些明显的错别字,我认为问题可能只是all_subproblems[i]的分配 【参考方案1】:

您还没有为all_subproblems 的每个元素分配内存来指向。

使用malloc() 分配此内存。而read() 的参数应该是数组元素,而不是数组元素的地址。

  // merge cells
  int** all_subproblems = malloc(sizeof(int*) * process_cnt);
  for (int i = 1; i < process_cnt; i++) 
    close(child_pipes[i][1]); // close writing end
    all_subproblems[i] = malloc(subproblem_sizes[i]);
    read(child_pipes[i][0], all_subproblems[i], subproblem_sizes[i]);
    close(child_pipes[i][0]); // close read end
  

【讨论】:

以上是关于使用管道()从多个子进程中读取?的主要内容,如果未能解决你的问题,请参考以下文章

通过管道从多个子进程写入父进程

使用重定向的标准输入处理子进程中的 kbhit

C管道写入/读取双打序列失败

持久的子进程管道 - 没有读取标准输出

在多个进程写入时读取命名管道

C Linux 编程 - 管道使子进程退出