【问题标题】:perl - child process signaling parentperl - 子进程向父进程发送信号
【发布时间】:2012-05-17 07:16:13
【问题描述】:

我编写了以下代码来测试孩子和父母之间的信号。理想情况下,当孩子向父母提供 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;
        }
    }

}

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

【问题讨论】:

  • 抱歉,无法重现。
  • Windows 既没有 fork 也没有信号。这些是unix概念。 Perl 模仿它们。你的问题源于此。
  • 是的,fork() 和信号仿真在 Windows 上使用最新版本的 Perl 会变得更好。您可能希望直接从 Win32::IPC 使用 Windows 同步对象。

标签: perl fork multiprocessing signals kill


【解决方案1】:

5.6.X 上的失败可能是因为 Perl 处理信号的方式,已通过 'Safe Signal Handling' in Perl 5.8.0 修复。在任何一种情况下,您使用的 Perl 实际上都具有考古价值,您应该向您的主人强烈主张您应该至少使用 Perl 5.12,最好是 5.14。

【讨论】:

    【解决方案2】:

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

    在您的情况下,最好在fork() 调用之前设置SIGINT 处理程序,这样您就知道在孩子尝试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;
            }
        }
    }
    

    【讨论】:

    • 在尝试不同的事情时,我通过适当地使用“睡眠”来确保没有竞争条件。无论如何,这很可能是原因。
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    相关资源
    最近更新 更多