vbruno has asked for the wisdom of the Perl Monks concerning the following question:

I am new to the perl fork function, and I am not sure that it does what I am looking for.

I have 2 long running subs. Sub1 I only want to run serially, sub2 I would like to fork off and not wait for a return. Here is psuedocode to illustrate (in my current implementation that has no forking):
#! /usr/local/bin/perl use Mod1; use Mod2; my @nodes = ("switch1", "switch2", "switch3", "switch4", "switch5"); foreach my $node_name (@nodes) { # a 4-10 minute TL1 conversation using Expect my $port_hashref = Mod1->sub1($node_name); # a five minute series of SQL queries using DBI Mod2->sub2($node_name, $port_hashref); }
I do not want to wait for sub2 to finish on a switch name before moving on to sub1 on the next switch name. I do not care about a return value from sub2.

With my limited understanding of fork, I expect it will fork the entire program instead of my sub2 code block and that it won't be easy to pass in my hash ref to sub2 after the fork.

Any ideas on how to do this (with or without fork)?

Replies are listed 'Best First'.
Re: Forking sub inside a module
by JavaFan (Canon) on Jun 15, 2009 at 16:03 UTC
    The entire process will be forked, but both forks will continue running from the point the process forked. And since the data is also forked (copied), there's no problem. You'll get something like:
    foreach my $node_name (@nodes) { my $port_hashref = Mod1->sub1($node_name); my $pid = fork; die "Unable to fork: $!\n" unless defined $pid; unless ($pid) { # Child process. Mod2->sub2($node_name, $port_hashref); exit; # When done, child should terminate. } } 1 while -1 != wait; # Reap children.
      Oh, that isn't so hard! I was thinking the forked process would start over at the beginning.

      I am not clear on the last line. I understand that I will want to wait for the last child to finish before exiting the parent, but is there a less obfuscated way of saying that?
        There's nothing obfuscated there. Perhaps the 1 in void context is confusing you? It can be avoided as follows:
        while (-1 != wait) {}
Re: Forking sub inside a module
by John M. Dlugosz (Monsignor) on Jun 15, 2009 at 17:48 UTC
    You might also look at Perl Threads, available as of Perl 5.6. See the threads documentation.