原子向量的初始化

Initialisation of vector of atomics

考虑:

void foo() {
  std::vector<std::atomic<int>> foo(10);
  ...
}

foo 的内容现在有效吗?或者我是否需要显式循环并初始化它们?我已经检查了 Godbolt,它似乎很好,但是标准在这一点上似乎很混乱。

std::vector constructor says it inserts default-inserted instances of std::atomic<int>, which are value initialised 通过放置 new

我认为值初始化的这种效果适用:

2) if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor;

所以在我看来,原子是零初始化的。所以问题是,std::atomic<int> 的零初始化是否会产生有效对象?

我猜答案是"yes in practice but it's not really defined"?

注意:同意它是零初始化的,但并没有真正说明这是否意味着该对象有效。

你的担心是对的。根据标准,原子调用了默认构造函数,但是它们 not 被初始化为这样。这是因为默认构造函数没有初始化 atomic:

The default-initialized std::atomic<T> does not contain a T object, and its only valid uses are destruction and initialization by std::atomic_init

这在某种程度上违反了正常的语言规则,一些实现无论如何都会初始化(正如您所注意到的)。

话虽这么说,我还是建议您采取额外的步骤,以 100% 确保它们已根据标准正确初始化 - 毕竟您处理的是并发性问题,其中错误极难追踪。

有很多方法可以避免这个问题,包括使用包装器:

struct int_atomic {
   std::atomic<int> atomic_{0};//use 'initializing' constructor
};

即使默认构造函数被调用(它不是,因为它是微不足道的)it doesn't really do anything

零初始化显然不能保证产生有效的原子;这只有在偶然通过零初始化其所有成员创建有效原子时才有效。

而且,由于原子不可复制,您不能在向量构造函数中提供初始化值。

您现在应该遍历容器和 std::atomic_init 每个元素。如果您需要对此进行锁定,那很好,因为您已经出于同样的原因同步了向量的创建。