1. ホーム
  2. c

[解決済み] シグマクションとシグナルの違いは何ですか?

2022-04-29 02:03:25

質問

ここにあるアプリにシグナルハンドラを追加しようとしたところ、作者が sigaction() を使用して、他のシグナルハンドラをセットアップします。私は signal() . 慣習に従うと、私は sigaction() しかし、もし私がゼロから書くとしたら、どちらを選ぶべきでしょうか?

どのように解決するのですか?

使用方法 sigaction() やむを得ない理由がある場合を除きます。

signal() インターフェイスは、古さ(したがって可用性)に有利であり、C 標準で定義されています。 とはいえ、以下のような好ましくない性質があります。 sigaction() に明示的に追加されたフラグを使用しない限りは、回避することができます。 sigaction() を忠実にシミュレートできるようにするため、旧来の signal() の挙動を示します。

  1. signal() 関数は、現在のハンドラの実行中に他のシグナルが到着するのをブロックするわけでは (必ずしも) ありません。 sigaction() は、現在のハンドラが戻るまで他のシグナルをブロックすることができます。
  2. は、その signal() 関数は(通常)シグナルアクションをリセットして SIG_DFL (デフォルト)です。 つまり signal() ハンドラの最初の動作として、自分自身を再インストールしなければなりません。 また、シグナルが検出されてからハンドラが再インストールされるまでの間に脆弱性が生じ、その間に2回目のシグナルのインスタンスが到着すると、デフォルトの動作(通常は終了、時には予断を与える - 別名コアダンプ)が発生します。
  3. の正確な動作は signal() はシステムによって異なりますが、標準はそのような差異を許容しています。

これらは、一般的に sigaction() の代わりに signal() . しかし sigaction() は、より手間がかかることは否めない。

どちらを使うにせよ、次のようなシグナル・インターフェースに誘惑されないでください。 sighold() , sigignore() , sigpause() そして sigrelse() . の名目上の代替品です。 sigaction() しかし、これらはほとんど標準化されておらず、POSIXには本格的に使用するためというよりは後方互換性のために存在しているに過ぎません。 POSIX規格では、マルチスレッドプログラムでの動作は未定義であるとされていることに注意してください。

マルチスレッドプログラムとシグナルは、全く別の複雑な話です。 AFAIKは、両方の signal()sigaction() は、マルチスレッドアプリケーションでOKです。

コーンストークス 観察する :

の Linux man ページは signal() は言う。

   の効果 signal() をマルチスレッドプロセスで使用することは規定されていません。

したがって、私は sigaction() は、マルチスレッドプロセスで安全に使用できる唯一のものです。

それは興味深いですね。 この場合、Linuxのマニュアルページの方がPOSIXよりも制約が多い。 POSIXでは signal() :

プロセスがマルチスレッドである場合、またはプロセスがシングルスレッドで、その結果以外にシグナルハンドラが実行された場合。

  • を呼び出したプロセス abort() , raise() , kill() , pthread_kill() または sigqueue() ブロックされない信号を生成するために
  • 保留中のシグナルがブロック解除され、それを解除した呼び出しが戻る前に配信された場合

以外のオブジェクトをシグナルハンドラが参照している場合、その動作は未定義です。 errno と宣言されたオブジェクトに値を代入する以外の方法で、静的な保存期間を設定します。 volatile sig_atomic_t に記載された関数以外の本標準規格で定義された関数を呼び出した場合、または、シグナルハンドラが 信号の概念 .

そこでPOSIXでは signal() をマルチスレッドアプリケーションで使用することができます。

それにしても。 sigaction() は、基本的にすべての状況において好ましいものであり、ポータブルなマルチスレッドコードは sigaction() ただし、そうできない圧倒的な理由(例えば、"Standard C" で定義された関数だけを使用する、など - そして、そう、C11コードはマルチスレッドにすることができます)がある場合を除きます。 この回答の最初の段落にも基本的に書かれていることです。