Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

parallel functions

by micmac (Novice)
on Nov 07, 2012 at 21:11 UTC ( #1002746=perlquestion: print w/ replies, xml ) Need Help??
micmac has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm trying to run two functions in parallel thusly:

#!/usr/bin/perl use 5.014; my @child_pids; for my $cmd (\&test1, \&test2) { defined(my $child_pid = fork()) or die "Couldn't fork: $!"; if ($child_pid == 0) { exec $cmd->(); } else { push @child_pids, $child_pid; } } for my $pid (@child_pids) { waitpid($pid, 0); } sub test1 { sleep 3; say "in test1"; } sub test2 { sleep 2; say "in test2"; }
Output:
in test2 in test1 in test2
Say what? Why is it running test2 twice?
thanks for any responses

Comment on parallel functions
Select or Download Code
Re: parallel functions
by tobyink (Abbot) on Nov 07, 2012 at 21:40 UTC

    Because the first fork creates two processes. One of those processes calls test1, the other does not. Then both processes fork again, creating a total of four processes; two of those processed call test2.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: parallel functions
by chromatic (Archbishop) on Nov 07, 2012 at 21:41 UTC
Re: parallel functions
by Anonymous Monk on Nov 07, 2012 at 21:53 UTC
    I did indeed mean exit.

    Thanks for both responses.

Re: parallel functions
by kcott (Abbot) on Nov 07, 2012 at 21:58 UTC

    G'day micmac,

    If you add use warnings;, you'll see that the exec is not being run at all:

    $ pm_child_execs.pl in test2 Can't exec "1": No such file or directory at ./pm_child_execs.pl line +13. in test1 Can't exec "1": No such file or directory at ./pm_child_execs.pl line +13. in test2 Can't exec "1": No such file or directory at ./pm_child_execs.pl line +13.

    What's actually happening is that $cmd->() is being run then exec is trying to use the return value ("1" from say) as its argument.

    So, the first child runs test1() then, because there's no exec, it runs test2() on the second iteration. The second child runs test2() (also with no exec). That's test1() once and test2() twice.

    Changing

    exec $cmd->();

    to

    #exec $cmd->(); $cmd->(); last;

    you'll get the desired output:

    $ pm_child_execs.pl in test2 in test1

    I'll leave you to decide if that's also the desired functionality.

    -- Ken

      Good explanation, thanks Ken.
Re: parallel functions
by marioroy (Acolyte) on Nov 25, 2012 at 06:26 UTC

    A new parallel module was recently added to CPAN called MCE. This is how one could run 2 functions in parallel using MCE.

    #!/usr/bin/perl use 5.014; use MCE; my $mce = MCE->new( max_workers => 2, user_func => sub { my $self = shift; if ($self->wid == 1) { test1(); } else { test2(); } } ); $mce->run(); sub test1 { sleep 3; say "in test1"; } sub test2 { sleep 2; say "in test2"; }

    Output

    in test2 in test1

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1002746]
Approved by nemesdani
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2014-09-21 07:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (167 votes), past polls