in reply to Stop fork in Parallel::ForkManager

I read the Synopsis and Description of Parallel::ForkManager because I was puzzled by the "and next" semantics in the call to start(). In the docs, it says, "The "and next" skips the internal loop in the parent process." Which internal loop is this? The surrounding foreach? Wouldn't that cause the rest of the foreach code to be skipped for the current iteration? In short, I'm still not clear on why the "and next" is required, and what it actually does. Would anyone be willing and able to comment on this? Thanks in advance.

Replies are listed 'Best First'.
Re^2: Stop fork in Parallel::ForkManager
by Anonymous Monk on Sep 27, 2009 at 05:59 UTC
    start/fork duplicates the current process, and both the original process (parent) and the copy (child) continue executing from that same point
    #!/usr/bin/perl -- use strict; use warnings; use Parallel::ForkManager; my $pm = new Parallel::ForkManager(3); for my $data ( 0 .. 2 ){ my $pid = $pm->start and next; ## WITH NEXT # my $pid = $pm->start ; ## WITHOUT NEXT print "data ($data) pid ($pid) \$\$($$)\n"; $pm->finish; # Terminates the child process } __END__
    The above program (with next) outputs
    data (0) pid (0) $$(-1792) data (1) pid (0) $$(-1856) data (2) pid (0) $$(-1916)
    The above program modified (without next) outputs
    data (0) pid (-1944) $$(1992) data (1) pid (-1656) $$(1992) data (1) pid (0) $$(-1656) data (0) pid (0) $$(-1944) data (2) pid (-1924) $$(1992) data (2) pid (0) $$(-1924)
    When pid is 0, it is the child process, when it is not zero, it is the parent process.

    Fork (operating system)

    Mr. Peabody Explains fork()

      You answered my question perfectly (I confess I'm new to the IPC game; actually I started reading that part of the Llama today). Good links. :)

      In regards to the original question...I found this code on wikipedia, and it seems to do what you want(?).

      #!/usr/bin/perl $pid = fork(); #Declare fork if ($pid == 0) { #Jump into the Child process for ($j = 0; $j < 10; $j++) { print "child: $j\n"; sleep 1; } exit(0); #Exit the fork [child process] } elsif ($pid > 0) { for ($i = 0; $i < 10; $i++) { print "parent: $i\n"; sleep 1; } exit(0); #Exit parent }

      So the thing here is to test the pid. In your code, you would say:

      $pm->finish if ($pid == 0 && $content =~ m/string/); #...no match, do more work... $pm->finish;

      Or am I totally missing the boat here (likely)? :)

        Thanks for all the replies

        Urthas, you did not miss the boat here because your code looks to be a crude version of what I am looking for and I'm thinking a more elegant solution doesn't exist.

        the reason I call your code crude is because, while it works, it kills off each child one-by one instead of killing the remaining children all at once. I guess I was looking for a bomb ...but bullets will do

        thank you
        thanks for the replies.

        Urthas your solution is usable and I appreciate it.
        You can also supply $pm->finish() with a parameter. I use it on my monitor scripts to keep track of how many successful connections to servers I've made. I return 0 for failure and 1 for success, so I just add them up and get 'X out of Y servers'. Works perfectly.

        I don't know if you can return more than a scalar offhand, but if you could return any type of variable (array/hash/etc), it could be very useful for communicating between a child and parent process. It just doesn't help at all with child->child communication.
        /\ Sierpinski