6

Perl に明示的にシグナルを無視するように指示した場合、SIGINT は効果がありません:

$SIG{INT} = 'IGNORE';
my $count = 0;
say $count++ and sleep 1 while 1;

次に Control-C を押しても、明らかに効果はありません。一方、何もしないように指示した場合:

$SIG{INT} = sub { };
my $count = 0;
say $count++ and sleep 1 while 1;

Control-C を押すと効果があります。sleep() 呼び出しからプログラムを起動し、すぐにカウントを増やします。信号を無視することと、何もしないように指示することの違いは何ですか?

私のプログラムでは、何も中断することなく、SIGINT でコードを実行したいと考えています。私は次のようなものが欲しい:

$SIG{INT} = sub { say "Caught SIGINT!"; return IGNORED; };  # runs without disrupting sleep
4

3 に答える 3

13

信号を無視することと何もしないように指示することの違いは何ですか?

「何もしない」ハンドラーは、シグナルが配信されたときに引き続き呼び出され、sleepこの場合は呼び出しを中断します。一方、無視された信号はシステムによって単に破棄され、プロセスには何の影響もありません。

C固有ですが、より包括的なリファレンスについては、ここを参照してください。

于 2009-07-28T13:38:50.967 に答える
6

多くのシステム コールは、シグナル配信によって中断される可能性があります。通常、チェック$!(aka errno) しているかどうかを確認EINTRし、失敗したシステム コールを再試行するためのアクションを実行できます。

コードの特定のセクション (この場合は への呼び出しsleep()) が中断されないことがPOSIX::sigprocmask重要な場合は、クリティカル セクションにいる間、 を使用してシグナルをブロックできます。アプリケーションが受信したシグナルは、ブロックを解除するまでキューに入れられ、ブロックが解除された時点で配信されます。特定のタイプの複数のシグナルがブロックされている場合、いくつかの面白いセマンティクスがあると確信しています (それらは単一のシグナルに合体する可能性があると思います)。

これは、再入可能関数に関する IBMの優れた入門書sigprocmaskで、 を使用した小さなサンプルが含まれています。

于 2009-07-28T15:29:53.950 に答える
1

なぜ期待どおりに機能しないのかわかりませんが、通常、同様のことを実行しようとすると、INT信号に加えてTERM信号もトラップします。

于 2009-07-28T13:38:03.900 に答える