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.