私のLinuxボックスでは、sig_atomic_t
は昔ながらのint
です。 ints
は特別な原子品質を持っていますか?
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
...
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1)
$ echo '#include <signal.h>' | gcc -E - | grep atomic
typedef int __sig_atomic_t;
typedef __sig_atomic_t sig_atomic_t;
C99 sig_atomic_t
は、「原子性」の非常に弱い定義にのみ準拠しています。これは、C99には並行性の概念がないであり、割り込み可能性のみであるためです。 (C2011は同時実行モデルを追加し、それを使用すると、より強力な保証を行う_Atomic
タイプが追加されます。ただし、raisond'êtreは引き続きシグナルと通信しているため、AFAIK sig_atomic_t
は変更されません。ハンドラー、スレッド間ではありません。)
これは、C99がsig_atomic_t
について言うすべてです。
(§7.14
<signal.h>
、段落2)定義された型はsig_atomic_t
です。これは、アトミックエンティティとしてアクセスできるオブジェクトの(おそらく揮発性修飾された)整数型です。非同期割り込み。 (§7.14<signal.h>
、パラグラフ2)(§7.14p5)
abort
またはraise
関数を呼び出した結果以外で[a]シグナルが発生した場合、シグナルハンドラーが静的ストレージ期間を持つオブジェクトを参照すると、動作は定義されません。volatile sig_atomic_t
として宣言されたオブジェクトに値を割り当てる以外の方法。(§7.18.3他の整数型の制限、段落3)
sig_atomic_t
(7.14を参照)が符号付き整数型として定義されている場合、SIG_ATOMIC_MIN
の値は-127以下である必要があります。SIG_ATOMIC_MAX
の127以上でなければなりません。それ以外の場合、sig_atomic_tは符号なし整数型として定義され、SIG_ATOMIC_MIN
の値は0、SIG_ATOMIC_MAX
の値は255以上でなければなりません。
「原子エンティティ」という用語は、標準のどこにも定義されていません。標準的なものから翻訳すると、intentは、CPUが1つのマシン命令でメモリ内のタイプsig_atomic_t
の変数(「静的ストレージ期間」)を完全に更新できることです。したがって、同時実行性がなく、正確に割り込み可能なC99抽象マシンでは、シグナルハンドラーがタイプsig_atomic_t
更新の途中の変数を監視することは不可能です。 §7.18.3p3言語では、必要に応じてこのタイプをchar
と同じくらい小さくすることが許可されています。プロセッサ間の一貫性に関連する言語の完全な不在に注意してください。
char
より大きい値をメモリに書き込むために複数の命令を必要とする実際のCPUがあります。値マシンワードよりも小さい(多くの場合、必ずしもそうとは限りませんが、int
と同じ)をメモリに書き込むために複数の命令を必要とする実際のCPUもあります。 GNU Cライブラリマニュアルの言語は現在不正確です。これは、C実装が命を吹き込んだ奇妙なことをするための不要なライセンスと見なしたものを排除したいという、元の作成者の願望を表しています。アプリケーションプログラマーにとっては難しい。残念ながら、そのライセンスこそが、一部の実際のマシンでCを使用できるようにするものです。int
もポインターもできない組み込みLinuxポート(AVRへの)が少なくとも1つあります。 1つの命令でメモリに書き込まれます(人々はマニュアルをより正確にするために取り組んでいます。例えば http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html -を参照してください。 --sig_atomic_t
は、その1つでは見逃されているようです。)
特定のタイプでは、読み取り/書き込みに複数の命令が必要になる場合があります。 int
タイプは常にアトミックに読み取り/書き込みされます。
データ型:sig_atomic_t
これは整数データ型です。このタイプのオブジェクトは常にアトミックにアクセスされます。
実際には、intおよびint以下の他の整数型はアトミックであると想定できます。ポインタ型はアトミックであると想定することもできます。それはとても便利です。これらは両方とも、GNU Cライブラリがサポートするすべてのマシン、および私たちが知っているすべてのPOSIXシステムに当てはまります。