sbnarra
sbnarra

Reputation: 584

Perl: fork creates new PID but parent doesn't continue

I'm trying to write some code to execute a long running process(simulated with a sleep, will actually be a call to a DB stored procedure) and wait till it's completed whilst asynchronously printing updates.

Below is what I have so far...

code...

#!/usr/bin/perl

use strict;
use warnings;

use 5.8.8;

my $pid1 = fork();
if( $pid1 == 0 ){
   print "starting long running process: $$\n";
    foreach (1..10) {
        sleep 1;
        print "sleep $_\n";
    }   
   print "completed long running process\n";
   exit 0;
}

print "making sure long running process is complete: $$\n";
while (1) {
    my $child = waitpid(-1, 0); 
    last if $child eq -1; 
    print "$child is still running\n";
    sleep 1;
}

print "child PID:$pid1. Process has now completed: $$\n";
exit 0;

output....

making sure long running process is complete: 27280
starting long running process: 27281
sleep 1
sleep 2
sleep 3
sleep 4
sleep 5
sleep 6
sleep 7
sleep 8
sleep 9
sleep 10
completed long running process
27281 is still running
child PID:27281. Process has now completed: 27280

So I can see there has been a child process created but why are my "still running" message not being printed till just after the child process has completed? (I'm expecting 9/10 of them but only get the one)

Upvotes: 1

Views: 190

Answers (1)

mob
mob

Reputation: 118595

Because waitpid($pid, 0) does not return until it has reaped a process or determined that there are no more child processes to reap.

If you want to do a non-blocking wait, use the WNOHANG flag as the perldoc explains:

use POSIX ':sys_wait_h';
...
while (1) {
    my $child = waitpid(-1, WNOHANG); 
    last if $child eq -1; 
    print "$pid1 is still running\n";
    sleep 1;
}

Upvotes: 4

Related Questions