Exemple #1
0
int parallelize_with_pipes(int numProcesses, int** A, int color) {
  // manages the critical section (printing) using pipes
  // see report for algorithm/reasoning

  pid_t this_pid;

  int turn_pipe[2]; // first pipe parent -> children
  int confirm_pipe[2]; // second pipe children -> parent

  int current_turn; // for turn_pipe
  int confirm_message; // for confirm_pipe

  int i;

  pipe(turn_pipe);
  pipe(confirm_pipe);

  switch (this_pid = fork()) {
    case -1:
      perror("fork() failure");
      break;
    case 0:
      // children processes
      close(confirm_pipe[0]); // only need to write to this
      do_pipes(numProcesses, 0, 0, A, color, turn_pipe, confirm_pipe);
      exit(0);
      break;
    default:
      close(confirm_pipe[1]); // only reads
      close(turn_pipe[0]); // only writes (children do both)

      // parent process handles the turns
      current_turn = 0;
      while (current_turn < numProcesses) {
        // tell children whose turn it is to print
        write(turn_pipe[1], &current_turn, sizeof(current_turn));
        // wait for confirmation that that child has printed
        read(confirm_pipe[0], &confirm_message, sizeof(confirm_message));

        if (confirm_message == current_turn) {
          current_turn++; // advance turn
        }
        // continue
      }
      // now all N processes have printed, exit
      break;
  }

  return 0;
}
Exemple #2
0
pid_t			execute_and_distrib(t_shell *sh, t_command *c)
{
	pid_t	child;
	pid_t	child2;
	int		pip[2][2];
	int		pip_sh[2][2];

	do_pipes(pip, pip_sh);
	child = my_fork();
	if (!child)
	{
		execute_all(sh, c, pip_sh, pip);
		handle_error_messages(sh);
		return (quit(sh, sh->last_status));
	}
	else
	{
		prepa_exec(sh, c, pip_sh, pip);
		child2 = distrib_and_send(sh, c, pip[0][0], pip[1][0]);
		wait_exec(child2, pip);
		return (child);
	}
}
Exemple #3
0
int do_pipes(int numProcesses, int level, int childNum, int** A, int color, int turn_pipe[2], int confirm_pipe[2])
{
  // child processes for pipe implementation
  // see report for pseudocode algorithm and reasoning

  // as this is a full binary tree, there are 2^level children
  int totalChildren = 1 << level;

  if (numProcesses <= totalChildren) {
    // compute filter
    int xStart = childNum * X / numProcesses; // start row
    int xEnd = (childNum + 1) * (X - 1) / numProcesses; // end row

    // run filter on just these rows
    colorFilter(A, xStart, xEnd, 0, Y-1, color); // rows

    // now this process waits until its turn to print is sent via turn_pipe
    int current_turn, confirm_message;
    while(1){ // loop indefinitely until its turn is over
      read(turn_pipe[0], &current_turn, sizeof(current_turn));

      if (current_turn == childNum){
          // it is this child's turn to print

          printf("Doing process %0.2d of %d.\n", childNum, numProcesses-1);
          printImage(A, xStart, xEnd, 0, Y-1);

          // send confirmation message to tell parent that it's done printing
          confirm_message = current_turn;
          write(confirm_pipe[1], &confirm_message, sizeof(confirm_message));

          // now stop waiting to process/print as we are done
          break;
      }

      // write back turn for the next process to read
      write(turn_pipe[1], &current_turn, sizeof(current_turn));
    }

  } else {
    // have not forked enough to create the necessary number of children
    // in our binary tree, so fork this process and recurse

    pid_t this_pid;
    int result;

    switch (this_pid = fork()) {
      case -1:
        perror("fork() failure");
        exit(-1);
        break;
      case 0: // this is the child
        do_pipes(numProcesses, level + 1, childNum * 2, A, color, turn_pipe, confirm_pipe);
        break;
      default: // parent
        do_pipes(numProcesses, level + 1, childNum * 2 + 1, A, color, turn_pipe, confirm_pipe);
        break;
    }
  }

  wait(NULL); // reliquish control until all children have printed and have died
  return 0;
}