Linux:为什么sig_atomic_t typedef需要inr?

时间:2012-03-07 18:01:10

标签: c linux signals

在我的Linux机器上,sig_atomic_t是一个普通的intints具有特殊的原子质量吗?

$ 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 个答案:

答案 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]信号不是作为调用abortraise函数的结果而发生,则如果信号处理程序引用具有静态存储的任何对象,则行为未定义持续时间,而不是为声明为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。

术语“原子实体”未在标准中的任何地方定义。从标准转换来看, 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系统   知道。

Reference