5
!/usr/bin/env perl
use POSIX;

my $sig_set = POSIX::SigSet->new(POSIX::SIGINT);
my $sig_act = POSIX::SigAction->new(sub { print "called\n"; exit 0 },$sig_set);

POSIX::sigaction(SIGINT,$sig_act);

sleep(15);

すでに欲しいとPOSIX::SigSet言っているのに、なぜ使用する必要があるのですか?POSIX::sigactionSIGINT

基本的に、SigSet に追加する各シグナルに coderef で応答しようとしていPOSIX::sigactionます。署名を見て、最初のパラメーターとしてシグナルを受け入れる必要がありPOSIX::SigActionますPOSIX::SigSet

ここで何かが欠けていると確信しています。

ありがとう、

4

1 に答える 1

6

あなたの質問への答え

POSIX::SigSetは、シグナル ハンドラ サブルーチンの実行中にマスクする (無視する) 追加シグナルを指定します。これは、 C バージョンの にsa_mask渡される基本構造体のメンバーに対応します。sigaction

現在、SA_NODEFER を介して明示的に要求しない限り、SIGINT (sigaction の最初の引数) はデフォルトでマスクされます。

より良いアプローチ?

ただし、登録されたシグナルによって実行が中断されないシグナルハンドラーを登録するためだけにやりたい場合 (たとえば、SIGINT ハンドラー中に SIGINT を許可しない場合)、POSIX モジュールを完全にスキップできます。 :

$SIG{INT} = sub { print "called\n"; exit 0; };  # Won't be interrupted by SIGINT

可能であれば、Perl のシグナル ディスパッチは、ハンドラーの実行中にシグナルをブロックする従来の UNIX セマンティクスをエミュレートします。(そして Linux では、それは確かに可能です。ハンドラーを実行する前に sigprocmask() が呼び出され、ユーザー提供のサブルーチンの最後でそのシグナルを再度許可するためにスコープ ガード関数が登録されます。)

于 2013-08-21T14:54:49.967 に答える