sigaction と signal はどう違いますか?

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

signal() インターフェースには古さ (したがって可用性) があり、C 標準で定義されています。それにもかかわらず、sigaction() という多くの望ましくない特性があります。 回避 - sigaction() に明示的に追加されたフラグを使用しない限り 古い signal() を忠実にシミュレートできるようにするため

<オール>
  • signal() 関数は、現在のハンドラーの実行中に他のシグナルが到着するのを (必ずしも) ブロックしません。 sigaction() 現在のハンドラーが戻るまで、他のシグナルをブロックできます。
  • signal() 関数は (通常) シグナル アクションを SIG_DFL にリセットします。 (デフォルト) ほぼすべての信号。これは、signal() ハンドラは、最初のアクションとして自身を再インストールする必要があります。また、シグナルが検出されてからハンドラーが再インストールされるまでの間に脆弱性のウィンドウが開かれ、その間にシグナルの 2 番目のインスタンスが到着すると、デフォルトの動作 (通常は終了し、場合によっては偏見を伴う - 別名コア ダンプ) が発生します。 /li>
  • signal() の正確な動作 システムによって異なります — 標準では、これらのバリエーションが許可されています。
  • これらは一般的に sigaction() を使用する正当な理由です signal() の代わりに .ただし、sigaction() のインターフェースは

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

    マルチスレッドのプログラムとシグナルは、まったく別の複雑な話です。 私の知る限り、両方とも signal()sigaction() マルチスレッド アプリケーションでは問題ありません。

    Cornstalks 氏は次のように述べています。

    それは面白い。この場合、Linux のマニュアル ページは POSIX よりも制限が厳しいです。 POSIX は signal() を指定します :

    したがって、POSIX は signal() の動作を明確に指定しています マルチスレッド アプリケーションで。

    それでも、sigaction() 基本的にすべての状況で優先されます — 移植可能なマルチスレッド コードは sigaction() を使用する必要があります それができない圧倒的な理由がない限り (「標準 C で定義された関数のみを使用する」など、そうです、C11 コードはマルチスレッド化できます)。これは基本的に、この回答の冒頭の段落にも書かれていることです.


    私にとっては、以下の行で十分に判断できました:

    http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html#tag_03_690_07

    ゼロから始める場合でも、古いプログラムを変更する場合でも、sigaction は適切なオプションです。


    これらは、OS のシグナル機能用の異なるインターフェイスです。 signal() には実装定義の (多くの場合競合しやすい) 動作があり、Windows、OS X、Linux、およびその他の UNIX システムでは動作が異なるため、可能であれば sigaction を使用してシグナルを送信することをお勧めします。

    詳細については、このセキュリティ ノートを参照してください。