追加の重要な注意: 「信頼できるシグナル」(sigaction
対応するsa_mask
フィールドを持つ POSIX) を使用している場合は、シングルスレッド、シングルプロセスの状況でシグナルがどのように動作するかを制御できます。
上記のようなシグナルハンドラーを持つ単一プロセス P1 の場合を考えてみましょう。シグナルSIGUSR1
をキャッチして、それを function に入れたとしますsignal_handler
。あなたが の中signal_handler
にいる間に、他のプロセス P2 が別のプロセスSIGUSR1
を P1 に送信します (たとえば、 を介して kill
)。この信号は、P1 に戻るsa_mask
まで(一時的に) 「ブロック」されます。signal_handler
これは、 にビットを設定しない場合でも当てはまります( に設定しsa_mask
ない限り、以下を参照してください)。SA_NODEFER
sa_flags
SIGUSR2
しかし、 functionでキャッチすることも決定したとしますsignal_handler
。P2 もSIGUSR2
. この場合、SIGUSR2
がキャッチされ (またはキャッチされる可能性があります) signal_handler
、今度はSIGUSR2
シグナルに代わって実行中の別のインスタンスが開始されます。
SIGUSR1
whenが処理されていることを確認することで、これを防ぐことができSIGUSR2
ます。一時的にもブロックされます。SIGUSR1
一般に、処理中はブロックしたいと思うでしょうSIGUSR2
。これを行うには、 の対応する両方のビットを設定しますsa_mask
。
struct sigaction sa;
memset(&sa, 0, sizeof sa);
sa.sa_flags = SA_RESTART | SA_SIGINFO; /* (decide for yourself which flags) */
sigaddset(&sa.sa_mask, SIGUSR1);
sigaddset(&sa.sa_mask, SIGUSR2);
sa.sa_sigaction = signal_handler;
error = sigaction(SIGUSR1, &sa, NULL);
if (error) ... handle error ...
error = sigaction(SIGUSR2, &sa, NULL);
if (error) ... handle error ...
この 2 つのsigaddset
呼び出しにより、関数の実行中は SIGUSR1 と SIGUSR2 の両方が保留 (一時的にブロック) されるようになります。
SA_NODEFER
シグナルを 1 つだけキャッチする場合、この余分な複雑さは必要ありません。 が設定されていない限り、OS はシグナル ハンドラへのエントリをトリガーしたシグナルを、エントリで設定された「現在ブロックされているシグナル」に自動的に追加するためです。
(シグナルハンドラへの入り口と出口でのシグナルの OS の自動ブロックとブロック解除はsigprocmask
、 を使用して、SIG_BLOCK
およびを使用して行われることに注意してください。実際に を呼び出すのではなく、カーネル コード内で実行しますが、効果は同じで、より効率的です)。SIG_SETMASK
SIG_UNBLOCK
SIG_SETMASK
SIG_BLOCK
sigprocmask