В моем ящике 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;
Ответ 1
C99 sig_atomic_t
соответствует только очень слабому определению "атомарности", поскольку C99 не имеет понятия concurrency, только прерывания. (C2011 добавляет модель concurrency, а вместе с ней типы _Atomic
, которые делают более надежные гарантии, однако AFAIK sig_atomic_t
не изменяется, поскольку его raison d'être все еще связывается с обработчиками сигналов, а не по потокам.)
Это все, что C99 говорит о sig_atomic_t
:
(§7.14 <signal.h>
, параграф 2) Определенный тип sig_atomic_t
, который является (возможно, волатильным) целым типом объекта, к которому можно получить доступ как к атомной сущности, даже при наличии асинхронного перебивает. (§7.14 <signal.h>
, параграф 2)
(§7.14p5) Если сигнал [a] встречается иначе, чем в результате вызова функции abort
или raise
, поведение undefined, если обработчик сигнала ссылается на любой объект со статической продолжительностью хранения чем путем назначения значения объекту, объявленному как 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.
Термин "атомный объект" не определен нигде в стандарте. Предполагается, что при переходе с стандартов на центральный процессор может полностью обновить переменную типа sig_atomic_t
в памяти ( "статическая продолжительность хранения" ) с одной машинной инструкцией. Таким образом, в concurrency -бесконечной, прерывистой абстрактной машине C99, обработчик сигнала не может наблюдать переменную типа sig_atomic_t
на полпути через обновление. Язык §7.18.3p3 позволяет при необходимости использовать этот тип как char
. Обратите внимание на полное отсутствие какого-либо языка, связанного с непротиворечивой последовательностью.
Существуют реальные процессоры, которым требуется более одной инструкции для записи значения, большего чем char
в память. Существуют также реальные процессоры, которым требуется более одной инструкции для записи значений меньше машинного слова (часто, но не обязательно, так же, как int
) в память. Язык в Руководстве по библиотеке GNU C теперь неточен. Он представляет собой желание со стороны первоначальных авторов устранить то, что они считают ненужной лицензией для реализаций C, чтобы сделать странное дерьмо, что усложнило жизнь программистам приложений. К сожалению, эта лицензия позволяет использовать C вообще на некоторых реальных машинах. Существует по крайней мере один встроенный Linux-порт (для AVR), для которого ни один int
, ни указатели не могут быть записаны в память в одной инструкции. (Люди работают над тем, чтобы сделать руководство более точным, см. например http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html - sig_atomic_t
, похоже, было пропущено в этом.)
Ответ 2
Некоторым типам может потребоваться несколько инструкций для чтения/записи. int
тип всегда читается/записывается атомарно.
Тип данных: sig_atomic_t
Это целочисленный тип данных. Объекты этого типа всегда доступны атомарно.
На практике вы можете предположить, что int и другие целочисленные типы больше не чем int, являются атомарными. Вы также можете предположить, что типы указателей неделимый; это очень удобно. Оба они верны для всех машин, которые поддерживает библиотека GNU C, и на всех POSIX-системах мы знать.
Ссылка