perl - 子进程信令父

时间:2012-05-17 07:16:13

标签: perl fork multiprocessing signals kill

我编写了以下代码来测试孩子和父母之间的信号。理想情况下,当子项向父项提供SIGINT时,父项应返回到新的迭代中并等待用户输入。我在perl 5.8中观察过,但在perl 5.6.1(我被要求使用)中,父母实际上是“被杀死”。没有下一次迭代。

my $parent_pid = $$;
$pid = fork();
if($pid == 0)
{   
    print "child started\n";
    kill 2, $parent_pid;
}
else
{
    while(1)
    {
        eval
        {
            $SIG{INT} = sub{die "GOTCHA";};
            print 'inside parent'."\n";
            $a = <>;
        };
        if($@)
        {
                print "got the signal!!!!\n$@\n";
                next;
        }
    }

}

有人可以为这个问题或其他方式提供一个解决方法,以便向父母发出信号,以便它进入新的迭代。

2 个答案:

答案 0 :(得分:3)

5.6.X上的失败可能是因为Perl用来处理信号的方式,这是用'Safe Signal Handling' in Perl 5.8.0修复的。在任何一种情况下,你使用的是一个实际上是考古学的Perl,你应该强烈地向你的主人争论你应该至少使用Perl 5.12,理想情况下是5.14。

答案 1 :(得分:2)

这可能是一种竞争条件,原因是孩子在父母准备好之前发送SIGINT。请记住,在fork()之后,您将拥有两个独立的流程,每个流程都可以按照自己喜欢的速度继续进行。

在您的情况下,最好在SIGINT调用之前设置fork()处理程序,因此您知道在孩子尝试kill()其父级之前它肯定已到位。

(稍作修改):

$SIG{INT} = sub { die "GOTCHA" };

my $parent_pid = $$;
defined( my $pid = fork() ) or die "Cannot fork() - $!";

if($pid == 0)
{   
    print "child started\n";
    kill INT => $parent_pid;
}
else
{
    while(1)
    {
        eval
        {
            print "inside parent\n";
            <>;
        };
        if($@)
        {
            print "got the signal!!!!\n$@\n";
            next;
        }
    }
}