Perl:fork创建新的PID,但父级不会继续

时间:2017-07-11 14:49:47

标签: perl unix fork

我试图编写一些代码来执行一个长时间运行的进程(用sleep模拟,实际上是对DB存储过程的调用)并等到它完成,同时异步打印更新。

以下是我到目前为止......

...代码

#!/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;

...输出

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

所以我可以看到创建了一个子进程,但为什么我的"仍在运行"在子进程完成之后才会打印消息? (我期待9/10,但只得到一个)

1 个答案:

答案 0 :(得分:4)

因为waitpid($pid, 0)在收到进程或确定没有更多子进程需要收获之后才会返回。

如果您想进行非阻塞等待,请使用WNOHANG标记perldoc解释:

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;
}