web-dev-qa-db-ja.com

sig_atomic_tは実際にはどのように機能しますか?

コンパイラまたはOSは、sig_atomic_t型と通常のint型変数をどのように区別し、操作がアトミックであることをどのように保証しますか?両方を使用するプログラムは、同じアセンブラコードを持っています。操作をアトミックにするためにどのように特別な注意が払われていますか?

24
Chu

sig_atomic_tはアトミックデータ型ではありません。シグナルハンドラーのコンテキストで使用できるのは、データ型だけです。そのため、名前を「シグナル処理に関連するアトミック」と読みやすくします。

シグナルハンドラーとの通信を保証するには、アトミックデータ型のプロパティの1つだけが必要です。つまり、読み取りと更新では常に一貫した値が表示されるという事実です。その他のデータ型(おそらくlong longなど)は、下位部分と上位部分のいくつかのアセンブラー命令で記述できます。 sig_atomic_tは、一度に読み書きできることが保証されています。

したがって、プラットフォームはsig_atomic_tとして整数の基本型を選択できます。これにより、volatile sig_atomic_tがシグナルハンドラーで安全に使用できることが保証されます。多くのプラットフォームがintを選択した理由は、intが単一の命令で記述されているためです。

最新のC標準であるC11にはアトミックタイプがありますが、これは完全に異なるものです。それらのいくつか(「ロックフリー」のもの)はシグナルハンドラーでも使用できますが、これもまったく別の話です。

25
Jens Gustedt

ご了承ください sig_atomic_tはスレッドセーフではなく、非同期シグナルセーフのみです。

アトミックには2種類の障壁があります。

  1. コンパイラのバリア。コンパイラーが、他の変数の読み取りおよび書き込みと比較して、アトミック変数の読み取り/書き込みの順序を変更しないようにします。これがvolatileキーワードの機能です。
  2. CPUバリアと可視性。これは、CPUが読み取りと書き込みの順序を変更しないようにします。 x86では、整列された1、2、4、8バイトのストレージへのすべてのロードとストアはアトミックです。可視性により、ストアが他のスレッドから見えるようになります。繰り返しますが、Intel CPUでは、ストアは キャッシュコヒーレンスおよびメモリコヒーレンスプロトコルMESI により、他のスレッドにすぐに表示されます。しかし、それは将来変わるかもしれません。詳細については、「インテル®64およびIA-32アーキテクチャソフトウェア開発者向けマニュアルボリューム3Aの§8.1ロックされた原子操作」を参照してください。

対象の時計の包括的な扱いについて アトミックウェポン:C++メモリモデルと最新のハードウェア

12

sig_atomic_tは、単なるtypedefです(システム固有の整数型には、通常intまたはlong)。そして、volatile sig_atomic_t (だけでなく sig_atomic_tのみ)。

volatileキーワードを追加すると、コンパイラーは多くの最適化を回避する必要があります。

最近の C11 標準が追加されました_Atomicおよび<stdatomic.h>。サポートするには、最新の [〜#〜] gcc [〜#〜] (例 4.9 )が必要です。

両方を使用するプログラムは、同じアセンブラコードを持っています。操作をアトミックにするためにどのように特別な注意が払われていますか?

これは古い質問ですが、質問のこの部分に具体的に取り組む価値はあると思います。 Linuxでは、sig_atomic_tはglibcによって提供されます。 glibcのsig_atomic_tintのtypedefであり、(この投稿の時点では)特別な扱いはありません。 glibc docs はこれに対処します:

実際には、intはアトミックであると想定できます。ポインタ型はアトミックであると想定することもできます。とても便利です。これらの両方の仮定は、GNU Cライブラリがサポートするすべてのマシンと、私たちが知っているすべてのPOSIXシステムで当てはまります。

つまり、通常のintは、glibcがサポートするすべてのプラットフォームでsig_atomic_tの要件をすでに満たしているため、特別なサポートは必要ありません。それにもかかわらず、CおよびPOSIX標準ではsig_atomic_tを義務付けています。これは、CおよびPOSIXを実装するエキゾチックなマシンでintsig_atomic_tの要件を満たさない場合があるためです。

1
Praxeolitic

このデータ型はアトミックなようです。
From here

24.4.7.2アトミックタイプ変数へのアクセスの中断に関する不確実性を回避するために、アクセスが常にアトミックである特定のデータタイプsig_atomic_tを使用できます。このデータ型の読み取りと書き込みは単一の命令で行われることが保証されているため、ハンドラーがアクセスの「途中」で実行することはできません。

型sig_atomic_tは常に整数データ型ですが、どのデータ型であり、それに含まれるビット数は、マシンによって異なります。

データ型:sig_atomic_tこれは整数データ型です。このタイプのオブジェクトは常にアトミックにアクセスされます。

実際には、intはアトミックであると想定できます。ポインタ型はアトミックであると想定することもできます。とても便利です。これらの両方の仮定は、GNU Cライブラリがサポートするすべてのマシンと、私たちが知っているすべてのPOSIXシステムで当てはまります。

0
jplozier