in reply to Parallel::ForkManager vs global variables
Actually this does exactly what you ask it to do. @values holds two values (0,0). When you hit the loop the first time you fork a child using the $pm->start method. As $pm->start will be true for the parent (value == child pid) the parent does the next (thus prints nothing). $pm->start is false for the child so the child does the stuff in the loop. In this loop you print $value (0) then change $value to 1 and print this. The array @values has been changed *but this is the child's copy of that array* Changing the @values array in the child does not change the @values array in the parent as you expect it to. You then kill this child. So far we have printed 01.
Although we did indeed modify @values in the now deceased child process we have not modified @values in the parent. When you fork parent and child get identical copies of the data structures, not a common shared copy as you seem to be expecting.
The parent (which we sent off with the next) then forks a second child that behaves identically, thus we print another 01.
As we have not changed @values in the parent the final loop in the parent prints 00. What you want to do is pass information from the child to the parent. This is called interprocess communication. Here is an example. We need to set some pipes to talk along (we need two as the are unidirectional) and set autoflush on them:
pipe (FROM_CHILD, TO_PARENT) or die "Oops Pipe: $!\n"; pipe (FROM_PARENT, TO_CHILD) or die "Oops Pipe: $!\n"; select((select(TO_CHILD), $|++ )[0]); # set autoflush select((select(TO_PARENT), $|++ )[0]); # set autoflush my @values = qw( value1 value2 value3 ); print "Before forking \@values:\n"; print "$_\n" for @values; for my $value (@values) { print "\nLoop value $value\n"; # let's fork if ( my $pid = fork ) { # this is parent print TO_CHILD "$value\n"; # send $value to child chomp( my $child_says = <FROM_CHILD> ); print "Child says '$child_says' to parent\n"; $value = $child_says; # change $value and thus @values for par +ent waitpid( $pid, 0 ); } else { # this is child die "Can't fork: $!\n" unless defined $pid; chomp( my $parent_says = <FROM_PARENT> ); print "Parent says '$parent_says' to child\n"; print TO_PARENT "Child pid $$ replies '$parent_says'\n"; exit; } } close FROM_CHILD; close TO_CHILD; close FROM_PARENT; close TO_PARENT; print "\nAfter forking \@values:\n"; print "$_\n" for @values;
As you can see we can talk back and forth (parent <-> child) across our pipes and the values in the parent process array get changed as a result of processing that occured in the child.
This is just a demo of communication and will not actually solve your problem as you want to fork off multiple children that run simultaneously. This is more complex. Basically you need to fork them all off and wait on them rather than fork and wait as this does. I'll leave it to you to sort the details :-)
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Parallel::ForkManager vs global variables
by Ntav (Sexton) on Sep 02, 2001 at 21:09 UTC |