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

ok before i rip my hair out.. trash my sun box & turn to drink... can someone point me in the right direction for forking new process.. i've read lots of articles on the site.. but confused with a lot of $pid examples... as I understand it..
$pid=fork; if ($pid==0) {try and start new process with exec??} elsif ($pid) {do what I want to do with this script??} else {die because of fork error }
which I think is right.. but just so confused about where it fits in with my script :-(
while (1) { my $time = time(); print $sock "$data\r\n"; my @output; my $output = join( '', @output ); while (<$sock>) { if ( $output = /$match/ ) { print STDOUT; open(STDOUT, "| $email"); last; } else { print STDOUT; open(STDOUT, "| $logger"); last; } } }

janitored by ybiC: Retitle from "newbie in a mucking fuddle" for better site searching

Replies are listed 'Best First'.
Re: Confused by fork examples
by ambrus (Abbot) on Dec 18, 2005 at 11:49 UTC

    Beware, I think this code you gave is wrong:

    $pid=fork; if ($pid==0) {try and start new process with exec??} elsif ($pid) {do what I want to do with this script??} else {die because of fork error }
    If fork gives an error, it will execute the first body; the third body is never executed.

    The correct way is to use the defined function to test for an error, something like this:

    use warnings; $pid = fork; if (!defined($pid)) { die "fork error"; } elsif (!$pid) { #line 6 "child" warn "starting"; for (1 .. 5) { sleep 1; warn "working hard. really. ", $_*20, "%"; } exit; # or exec } else { #line 14 "parent" warn "starting the parent"; for (1 .. 2) { sleep 1; warn "doing some work"; } warn "waiting for the child to finish (or just collecting it if it + has finished"; $pid == waitpid($pid, 0) or die "error waiting: $!"; 0 == $? or die "child has died"; warn "ok, collected the child successfully"; } __END__
      ambrus,
      To quote the docs: It returns the child pid to the parent process, 0 to the child process, or undef if the fork is unsuccessful.

      I believe the 3rd block would be executed if fork failed because it would return undef not 0?

      Update: Specifically, I am referring to your comment If fork gives an error, it will execute the first body; the third body is never executed. I now see your point. If the $pid is undef then ($pid == 0) won't work as intended. Thanks.

      Cheers - L~R

        In the CB, you were looking for documentation that I know I had seen in the past. mr_mischief jogged my memory as to where it was.

        • pink camel, under fork() (page 146)
        • blue camel, under fork() (page 167)

        hth

        --MidLifeXis

Re: Confused by fork examples
by reasonablekeith (Deacon) on Dec 18, 2005 at 11:28 UTC
    You don't need to start new process with eval, when you run 'fork' you will already have two exact copies of you program running.

    fork creates this dupicate in a child process of the one running the original perl script. The way you tell them apart is by checking the id returned from fork. If the id is 0, you are in the child process. If the id is non-zero, you are in the parent. That non-zero id is the id of the spawned child process.

    so, after running fork, check the id and condition your code appropriately for the child or the parent

    ---
    my name's not Keith, and I'm not reasonable.
Re: Confused by fork examples
by QM (Parson) on Dec 18, 2005 at 16:08 UTC
    There are a lot of other issues to consider when forking, such as waiting for children, zombies, communication between processes, and portability.

    I posted a script here a couple of years ago that solved most of my problems (but I've never had any comments on it). Maybe it will give you some insight.

    I'm unsure whether you want to communicate with the forked children, or let them run freely. Otherwise, I think you can use my script as a template. (I'd be interested in any feedback :)

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of