这不是关于静态初始化和线程安全的问题。由于C++ 11中使用了该标准中的措辞,因此可以一起保证它们。
到现在为止还挺好。请考虑以下类:
struct S {
static int id() noexcept {
static int v = 0;
return v++;
}
template<typename>
static int value() noexcept {
static const int v = id();
return v;
}
};
在这种情况下,在不同线程上对
S::value<MyType>()
的两个并发调用是安全的(如果我错了,请纠正我)。两个并发调用(如
S::value<AType>()
和S::value<AnotherType>()
)也安全吗?据我所知,由于专业不同,
value
本身根本不是问题。但是,当涉及到调用id
时,保证第一行(静态初始化)是线程安全的,但是紧随其后的那一行并不适用。因此,
v
中的AType
和AnotherType
可以具有相同的值。另一方面,在
value
中对id
进行静态初始化期间会调用v
,因此我不确定我期望的有效性。这就是为什么我问。我的推理是否有问题,或者上面的代码实际上不是线程安全的?
最佳答案
不需要。您必须进行同步,但是在您的情况下,它非常简单:
struct S {
static int id() noexcept {
static std::atomic<int> v { 0 };
return ++v;
}
template<typename>
static int value() noexcept {
static const int v = id();
return v;
}
};
请注意,避免后期增加是一种很好的做法。
关于c++ - 线程安全和静态变量/成员函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49013297/