2015-11-04 40 views
1

所以我想创建一个Perl程序,分叉工人,并等待它完成。在我的真实使用案例中,我需要分派许多工作人员并等待他们,所以我想我会尝试一个工作人员的测试用例。我在这里担心的是,当我在终端中运行此程序时,发送^C不会终止父进程,即使信号处理程序看起来应该收获子进程并导致父进程正常退出。我试图使用waitpid来保持父母活着,以便它可以接收信号并将它们传递给孩子,但父母过程似乎完全忽略^CPerl转发信号SIGINT分叉子进程

use strict; 
use warnings FATAL => 'all'; 
use POSIX ":sys_wait_h"; 

my $cpid; 

sub reap_children_and_exit { 
    defined $cpid and kill 'HUP', $cpid; 
    exit 0; 
} 

$SIG{INT} = \&reap_children_and_exit; 

my $child_text = <<'EOF'; 
perl -e 'while (1) { printf "%s\n", rand() }' 
EOF 

$cpid = fork; 
if ($cpid == 0) { 
    exec($child_text) 
} 

waitpid($cpid, WNOHANG); 

回答

3

我试图用waitpid函数,以保持父活着

你告诉waitpid立即返回。将WNOHANG更改为0

+0

'waitpid'的文档页面(http://perldoc.perl.org/functions/waitpid.html)有点稀疏。这个函数是否意味着对于Linux系统调用来说是一个相当薄的包装(带有将其连接到其他系统的附加逻辑)? –

1

如果你不需要自己实现并且可以使用一个模块,我会建议:https://metacpan.org/pod/Parallel::Prefork 这个模块很容易地为你包装所有的工人/孩子的创建和管理,此外它还节省了内存使用量。

如果您打算创建一个守护进程,还有另外一个,它可以管理叉:https://metacpan.org/pod/Daemon::Control

或尝试这种解决方案:

use strict; 
use warnings FATAL => 'all'; 
use feature 'say'; 
use POSIX ":sys_wait_h"; 

BEGIN { 
    sub reap_children_and_exit { 
     my $signame = shift; 
     my $pid = shift; 
     defined $pid and kill $signame, $pid; 
     say "$pid => Received '$signame' !"; 
     exit 0; 
    } 
    $SIG{INT} = \&reap_children_and_exit; 
} 

my %children; 

$SIG{CHLD} = sub { 
    # don't change $! and $? outside handler 
    local ($!, $?); 
    while ((my $pid = waitpid(-1, WNOHANG)) > 0) { 
     delete $children{$pid}; 
     reap_children_and_exit('HUP', $pid); 
    } 
}; 

my $child_text = <<'EOF'; 
perl -e 'while (1) { printf "%s\n", rand(); sleep 1; }' 
EOF 

while (1) { 
    my $pid = fork(); 
    die "Cannot fork" unless defined $pid; 
    say "I'm the PID $pid"; 
    if ($pid == 0) { 
     say q{I'm the parent}; 
     exit 0; 
    } else { 
     $children{$pid} = 1; 
     system($child_text); 
    } 
} 

我希望这可以帮助你。 此致敬礼!

+0

否则,也许这可以帮助你:http://perldoc.perl.org/perlipc.html 或者,你可以尝试线程,如果可能的话:http://perldoc.perl.org/perlthrtut.html#NAME – eddy85br

+0

像这样发送不间断的HUP流是不对的。 – ikegami

+0

@ikegami你的答案更简单,更好,谢谢! – eddy85br