Reputation: 584
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
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