C11 stdatomic 和 calloc
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?
我猜这不是 portable/safe。
很可能 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
.
另见 deferred 归零。
不,这一般是不可移植的。 calloc
仅保证基础对象的字节 0
值。对于(可能)具有状态的类型,这不等同于初始化。您肯定必须使用 atomic_init
将您的对象置于有效状态。
这是因为除了基础对象之外还持有 "lock" 的平台,因为它们没有实现相应的汇编程序指令。因此,为了便携,您确实需要对所有非静态分配的原子对象使用 ATOMIC_VAR_INIT
或 atomic_init
。
就是说,我不知道有哪个现有平台会需要这样的东西 atomic_int
。如果您的平台将 ATOMIC_INT_LOCK_FREE
设置为 2
和 sizeof(atomic_int)==sizeof(int)
,您可以相对确定您的策略有效。您可以在 _Static_assert
.
中进行测试
我有一个包含原子字段的结构:
#include <stdatomic.h>
struct s {
...
atomic_int a;
};
此结构分配有calloc
:
struct s *p = calloc(1, sizeof(struct s));
期望p->a
初始化为0是否可移植?代码中有足够的障碍,因此弱一致初始化是可以的,但是初始值是否保证为 0?
我猜这不是 portable/safe。
很可能 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
.
另见 deferred 归零。
不,这一般是不可移植的。 calloc
仅保证基础对象的字节 0
值。对于(可能)具有状态的类型,这不等同于初始化。您肯定必须使用 atomic_init
将您的对象置于有效状态。
这是因为除了基础对象之外还持有 "lock" 的平台,因为它们没有实现相应的汇编程序指令。因此,为了便携,您确实需要对所有非静态分配的原子对象使用 ATOMIC_VAR_INIT
或 atomic_init
。
就是说,我不知道有哪个现有平台会需要这样的东西 atomic_int
。如果您的平台将 ATOMIC_INT_LOCK_FREE
设置为 2
和 sizeof(atomic_int)==sizeof(int)
,您可以相对确定您的策略有效。您可以在 _Static_assert
.