我有一个包含原子场的结构:
#include <stdatomic.h>
struct s {
...
atomic_int a;
};这个结构是用calloc分配的
struct s *p = calloc(1, sizeof(struct s));期望p->a初始化为0是可移植的吗?代码中有足够的屏障,所以弱一致的初始化很好,但是初始值是否保证为0呢?
发布于 2015-05-30 14:33:58
不,这在一般情况下是不能携带的。calloc只保证底层对象按字节排列的0值.对于(可能)具有状态的类型,这不等同于初始化。您最终必须使用atomic_init将对象置于有效状态。
造成这种情况的原因是平台除了基本对象之外还持有“锁”,因为它们没有实现相应的汇编程序指令。因此,要便于移植,您确实需要对所有未静态分配的原子对象使用ATOMIC_VAR_INIT或atomic_init。
尽管如此,我不知道有任何现有的平台需要这样的巡航atomic_int。如果您的平台将ATOMIC_INT_LOCK_FREE设置为2和sizeof(atomic_int)==sizeof(int),则可以相对确定您的策略是否有效。您可以在_Static_assert中测试这一点。
发布于 2015-05-29 17:14:18
我猜这不是便携/安全的。
很可能calloc()在内存区域做了一个简单的memset()。这个简单的memset()不会发出所需的内存屏障,以确保其他读取结构的线程将p->a视为0。
发布于 2015-05-29 18:15:36
struct s *p = calloc(1, sizeof(struct s));
struct s *q = p;
// some other thread
foo(*q);初始化到零是在p或它的任何一个子类能够访问内存之前进行的。是0。
也见deferred零点。
https://stackoverflow.com/questions/30535262
复制相似问题