Linux: почему sig_atomic_t typedef определен в 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;

2 ответа

Решение

C99 sig_atomic_t соответствует только очень слабому определению "атомарности", потому что у C99 нет понятия параллелизма, только прерывистость. (C2011 добавляет модель параллелизма, а вместе с ней _Atomic типы, которые дают более сильные гарантии; однако, AFAIK sig_atomic_t остается неизменным, поскольку его смысл все еще связан с обработчиками сигналов, а не между потоками.)

Это все, что C99 говорит о sig_atomic_t:

(§7.14 <signal.h>, пункт 2) Определенный тип sig_atomic_t, который является (возможно, изменчивым) целочисленным типом объекта, к которому можно обращаться как к элементарному объекту, даже при наличии асинхронных прерываний. (§7.14 <signal.h> пункт 2)

(§7.14p5) Если сигнал [a] возникает не в результате вызова abort или же raise функция, поведение не определено, если обработчик сигнала ссылается на любой объект со статической продолжительностью хранения, кроме как путем присвоения значения объекту, объявленному как 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 в памяти ("длительность статической памяти") с одной машинной инструкцией. Таким образом, в параллельном, точно прерываемом абстрактном автомате 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 кажется, что в этом не хватало.)

Для определенных типов может потребоваться несколько инструкций для чтения / записи. int Тип всегда читается / пишется атомарно.

Тип данных: sig_atomic_t

Это целочисленный тип данных. Объекты этого типа всегда доступны атомарно.

На практике вы можете предположить, что int и другие целочисленные типы не более int являются атомарными. Вы также можете предположить, что типы указателей являются атомарными; это очень удобно. Оба они верны на всех машинах, которые поддерживает библиотека GNU C, и на всех известных нам системах POSIX.

Ссылка

Другие вопросы по тегам