2
if (signal(SIGINT, SIG_IGN) != SIG_IGN) 
    signal(SIGINT, sig_int);

このコードは何度か見たことがあります。そして、それは私を混乱させます。これを行うと、シグナルが現在無視されていない場合にのみ、プロセスはシグナルをキャッチします。

私の質問は:

  1. signal(SIGINT, sig_int);最初のシグナル関数にエラーがなければ決して実行されないと思いますよね?

  2. どのような状況で(signal(SIGINT, SIG_IGN) != SIG_IGN)起こりますか?

4

2 に答える 2

2

1行ずつ、

if (signal(SIGINT, SIG_IGN) != SIG_IGN)

への呼び出しsignalは、前のアクションを返します。ここで何が起こっているかというと、シグナル ハンドラを に設定しSIG_IGN(つまり、シグナルを無視する)、戻り値をチェックして、それが既に無視されているかどうかを確認しています。以前に無視されていなかった場合は...

signal(SIGINT, sig_int);

...起こります。

そこで、「SIGINT が無視されているかどうかを確認し、無視されていない場合は、シグナル ハンドラーを sig_int に設定する」という別の表現を使用します。最初の行で実際にシグナルを SIG_IGN に設定して戻り値を比較するのは少し奇妙ですが、それが起こっていることです。

編集: signal() は SIG_ERR を返すこともできますが、これは考慮すべきことです。

于 2013-02-22T05:39:44.197 に答える
1

それはまさにsignalその通りで、以前の sig 値 (SIG_IGN) または壊れた場合は SIG_ERR を返します。したがって、コードが行っていることは、SIG_IGN にエラーを処理する際に問題がある場合 (エラーを記録して無視する)、プログラムは再びシグナルをキャッチし、それを関数 sig_int に渡し、別の方法で処理する必要があるということです。

ソース: http://linux.die.net/man/2/signal

それがいつ起こるかについては、ここのウェブサイトはこれを示しています:

シグナルが要求を受け入れることができない場合、代わりに SIG_ERR を返します。この関数には、次の errno エラー条件が定義されています。

EINVAL
You specified an invalid signum; or you tried to ignore or provide 
a handler for SIGKILL or SIGSTOP.

SIGKILL と SIGSTOP はキャッチまたはハンドリングできないため、2 番目のコマンドが呼び出される唯一の方法は、何らかの理由で SIG_IGN が間違っていた場合だと言いますか?

于 2013-02-22T05:38:32.970 に答える