Linux: Почему sig_atomic_t typedef'ed для int?

В моем ящике 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-системах мы знать.

Ссылка