2015-11-04 36 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