【发布时间】:2014-07-24 12:16:38
【问题描述】:
在 C++11 中,以下是线程安全的:
void someFunc()
{
static MyObject object;
}
但是呢
void someFunc()
{
static MyObject *ptr = new MyObject();
}
这是否是线程安全的?
正如@Nawaz 在 cmets 中提到的那样,MyObject 构造函数可能不是线程安全的,所以让我们将问题分成几部分:
1) 如果 ctor 是线程安全的(它不访问任何共享状态),这是 static MyObject *ptr = new MyObject(); 线程安全的吗?换句话说,static int *ptr = new int(0); 线程安全吗?
2) 如果 ctor 不是线程安全的,但对象仅通过从不同线程调用 someFunc 来创建,并且构造函数从未在其他任何地方使用,那么这将是线程安全的吗?
【问题讨论】:
-
static MyObject object;是 not 线程安全的,如果默认构造函数不是线程安全的,即如果它在内部访问可变共享资源,比如通过全局变量或单例。但是,static int object = 100;是 100% 线程安全的。 -
@Nawaz 考虑到您在评论中对我(现已删除)答案的引用,这是否表明这两个初始化实际上都是线程安全的? (有问题的引用是“如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成。”,来自 C++11 规范§6.7/ 4).
-
@JoachimPileborg:我不这么认为。标准仅保证这一点:如果多个线程尝试同时开始执行构造函数,则只有其中一个会实际执行它,其余的将等待初始化完成。然而,标准并没有对构造函数本身的线程安全提供任何保证。构造函数本身很可能是线程不安全的(例如,如果它访问 modifiable 全局资源)。
-
@Nawaz 换句话说,我们保证实际初始化是线程安全的,但不是多线程导致重新初始化?
-
只有一个线程会初始化
object,但object的构造函数可能不是线程安全的。
标签: c++ c++11 thread-safety static-initialization