在我的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;
答案 0 :(得分:34)
C99 sig_atomic_t
仅符合“原子性”的非常弱的定义,因为 C99没有并发概念,只有可中断性。 (C2011添加了一个并发模型,并使用了_Atomic
类型来提供更强的保证;但是,AFAIK sig_atomic_t
没有变化,因为它的存在理由仍在与信号处理程序,而不是跨线程。)
这是C99关于sig_atomic_t
所说的一切:
(§7.14
<signal.h>
,第2段)定义的类型是sig_atomic_t
,它是可以作为原子实体访问的对象的(可能是volatile限定的)整数类型,即使在存在异步中断。 (§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
的值不应大于-127SIG_ATOMIC_MAX
的值不得少于127;否则,sig_atomic_t被定义为无符号整数类型,SIG_ATOMIC_MIN
的值应为0,SIG_ATOMIC_MAX
的值应不小于255。
术语“原子实体”未在标准中的任何地方定义。从标准转换来看, intent 是指CPU可以使用一条机器指令完全更新内存中类型sig_atomic_t
的变量(“静态存储持续时间”)。因此,在无并发,精确可中断的C99抽象机器中,信号处理程序不可能在更新的中途观察类型为sig_atomic_t
的变量。如果需要,§7.18.3p3语言许可此类型与char
一样小。请注意完全缺席与任何与跨处理器一致性有关的语言。
有些实际的CPU需要多条指令才能将大于char
的值写入内存。还有一些真正的CPU需要多条指令才能将小于机器字的值(通常但不一定与int
相同)写入内存。 GNU C Library手册中的语言现在不准确。它代表了原作者希望消除他们认为不必要的C实现许可证的做法,这样做会让应用程序员的生活更加艰难。不幸的是,非常许可证使得在某些真机上拥有C成为可能。至少有一个嵌入式Linux端口(到AVR),在一条指令中,int
和指针都不能写入存储器。 (人们正在努力使手册更准确,但请参阅例如http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html - sig_atomic_t
似乎已经错过了该手册。)
答案 1 :(得分:6)
某些类型可能需要多条指令才能读/写。 int
类型始终以原子方式读/写。
数据类型:sig_atomic_t
这是整数数据类型。始终访问此类对象 原子。
实际上,您可以假设不再使用int和其他整数类型 比int是原子的。您还可以假设指针类型是 原子;这很方便。所有这些都是正确的 GNU C库支持的机器,以及我们所有的POSIX系统 知道。