3

子と親の間のシグナリングをテストするために、次のコードを記述しました。理想的には、子が親にSIGINTを与えるとき、親は新しい反復に戻ってユーザー入力を待つ必要があります。これは私がperl5.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;
        }
    }

}

誰かがこの問題のウォークアラウンド、または新しいイテレーションに入るように親に信号を送る他の方法を教えてください。

4

2 に答える 2

3

5.6.X での失敗は、Perl がシグナルを処理するために使用していた方法が原因である可能性があり、これはPerl 5.8.0 の「安全なシグナル処理」で修正されました。いずれの場合も、実質的に考古学的な Perl を使用しているため、少なくとも Perl 5.12、理想的には 5.14 を使用する必要があることをマスターに強く主張する必要があります。

于 2012-05-17T07:52:16.400 に答える
2

SIGINTこれは、親の準備が整う前に子が を送信したために発生した競合状態である可能性があります。2 つの独立したプロセスが作成された後は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;
        }
    }
}
于 2012-05-17T13:25:19.933 に答える