[英]C11 stdatomic and calloc
我有一个包含原子场的结构:
#include <stdatomic.h>
struct s {
...
atomic_int a;
};
这个结构分配了calloc
:
struct s *p = calloc(1, sizeof(struct s));
是否可以将p->a
初始化为0? 代码中有足够的障碍,因此初始化很弱,但是初始值是否保证为0?
不,这一般不便携。 calloc
仅保证底层对象的字节0
值。 对于(可能)具有状态的类型,这不等于初始化。 您肯定必须使用atomic_init
将对象置于有效状态。
这样做的原因是除了基础对象之外还包含“锁定”的平台,因为它们没有实现相应的汇编指令。 因此,为了便于移植,您确实需要对所有非静态分配的原子对象使用ATOMIC_VAR_INIT
或atomic_init
。
也就是说,我不知道任何现有的平台需要为atomic_int
这样的atomic_int
。 如果您的平台将ATOMIC_INT_LOCK_FREE
设置为2
并且sizeof(atomic_int)==sizeof(int)
,则可以相对确定您的策略是否有效。 你可以在_Static_assert
测试它。
我的猜测是这不便携/安全。
calloc()
很可能最终在内存区域做一个简单的memset()
。 这个简单的memset()
不会发出所需的内存屏障,以确保读取结构的其他线程会将p->a
视为0
。
struct s *p = calloc(1, sizeof(struct s));
struct s *q = p;
// some other thread
foo(*q);
在p
或其任何组件可以访问存储器之前考虑初始化为零。 它是0
。
另请参见延迟清零。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.