how to return values from several forks

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Marc Marc

    #1

    how to return values from several forks

    I'm working on a program that simulates a certain model with several paramters and returns one result value. I want to check how changing each parameter affects the result. What I did before was running the simulation with the base set of paramters to get a baseline and then change one parameter and run it again. Now I found out about fork() and can just run fork() for each set of parameters. This runs a lot faster, so it's preferrable.
    I want to return not the absolute result values of each parameter set but the difference to the base. I have learned how to let two processes communicate from http://docstore.mik.ua/orelly/perl/cookbook/ch16_11.htm, but it fails when I try to spawn several forks and get their result back.

    in pseudocode:
    Code:
    for parameter = each parameter_set
      fork()
    if parent
      base = sim(base_parameters)
      wait for return values
      print return1 - base, return2 - base etc
    else
      result = sim(parameter)
      return result
  • chorny
    Recognized Expert New Member
    • Jan 2008
    • 80

    #2
    Try using module like Child.

    Comment

    • Marc Marc

      #3
      found a solution (not elegant)

      Thanks for the answer chorny, but I need the script to be able to run on other machines without them installing extra modules, so that won't work.

      I have however found a solution that works if I know the number of children I need to spawn before runtime. It's far from elegant, but it works ;)

      Code:
      #!/usr/bin/perl -w
      # multifork test
      
      use IO::Handle;
      
      #prepare pipes, one per child
      pipe(READER0, WRITER0);
      WRITER0->autoflush(1);
      pipe(READER1, WRITER1);
      WRITER1->autoflush(1);
      pipe(READER2, WRITER2);
      WRITER2->autoflush(1);
      pipe(READER3, WRITER3);
      WRITER3->autoflush(1);
      
      if ($pid[0] = fork) { # i'm the parent
      	close WRITER0;
      	if ($pid[1] = fork) { # i'm still the parent
      		close WRITER1;
      		if($pid[2] = fork) { # i'm still the parent
      			close WRITER2;
      			if($pid[3] = fork) { # i'm still the parent
      				close WRITER3;
      			} else { # i'm child 3
      				die "cannot fork: $!" unless defined $pid[3];
      				close READER3;
      				# do childish stuff here
      				print WRITER3 "Child Pid $$ is sending this\n";
      				close WRITER3;
      				exit;
      			}
      		} else { # i'm child 2
      			die "cannot fork: $!" unless defined $pid[2];
      			close READER2;
      			# do childish stuff here
      			print WRITER2 "Child Pid $$ is sending this\n";
      			close WRITER2;
      			exit;
      		}
      	} else { # i'm child 1
      		die "cannot fork: $!" unless defined $pid[1];
      		close READER1;
      		# do childish stuff here
      		print WRITER1 "Child Pid $$ is sending this\n";
      		close WRITER1;
      		exit;
      	}
      } else { # i'm child 0
      	die "cannot fork: $!" unless defined $pid[0];
      	close READER0;
      	# do childish stuff here
      	print WRITER0 "Child Pid $$ is sending this\n";
      	close WRITER0;
      	exit;
      }
      
      # listen to your children:
      chomp($line[0] = <READER0>);
      chomp($line[1] = <READER1>);
      chomp($line[2] = <READER2>);
      chomp($line[3] = <READER3>);
      # print out what the children said
      print "Parent Pid $$ just read this: $line[0]\n";
      print "Parent Pid $$ just read this: $line[1]\n";
      print "Parent Pid $$ just read this: $line[2]\n";
      print "Parent Pid $$ just read this: $line[3]\n";
      #wait for children to finish
      for ($n=0;$n<=3;$n++) {
      	waitpid($pid[$n], 0);
      }

      Comment

      Working...