J. Auon
J. Auon

Reputation: 189

Reading from multiple child processes with pipe()?

I have a chunk of code where I am trying to split a problem into N subproblems across N child processes, having each process do work with its given subproblem, then merging the results back together via piping.

The size of each subproblem's solution is know ahead of time, in the form of an int array.

The issue appears to be that the subproblem solutions are not being read in by the main process. Trying to access the read in data afterwards gives a NULL pointer error. I think the cause may be due to the exiting of child processes before the data is read in, but I have been unable to verify this in my own experimentation.

The code I am using looks roughly like this

  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
  }

I am not sure if I am using fork() and pipe() incorrectly here, but that certainly may well be the issue. Any help would be greatly appreciated!

Upvotes: 0

Views: 268

Answers (1)

Barmar
Barmar

Reputation: 780723

You haven't allocated memory for each element of all_subproblems to point to.

Use malloc() to allocate this memory. And the argument to read() should be the array element, not the address of the array element.

  // 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
  }

Upvotes: 1

Related Questions