Kav*_*veh 3 c++ multithreading gcc thread-safety c++11
我知道以下是在C++ 11中实现单例的一种线程安全的方法:
Foo* getInst()
{
static Foo* inst = new Foo(...);
return inst;
}
Run Code Online (Sandbox Code Playgroud)
我在这个答案中读到以下内容也是线程安全的:
Foo& getInst()
{
static Foo inst(...);
return inst;
}
Run Code Online (Sandbox Code Playgroud)
它真的是线程安全的吗?将
Foo的实例分配到单个堆栈帧中不会在堆上分配是不是一个问题?
如果它是线程安全的,是否有充分的理由选择一个到另一个?
静态变量不是在堆栈上分配.在第一个变体中,您有一个静态指针(一个全局变量),它是用从堆中获取的内存初始化的,而在第二个变体中,您有一个完整的静态对象.
这两个版本使用编译器内部警卫(即__cxa_guard_acquire()
和__cxa_guard_release()
,在功能上等同于mutex::lock()
和mutex::unlock()
),以确保以一个特殊的变量,它告诉你的全局实例是否已经被初始化或没有序列号的访问.
你的代码:
Foo& getInst()
{
static Foo inst(...);
return inst;
}
Run Code Online (Sandbox Code Playgroud)
编译后实际上看起来像这样:
Foo& getInst()
{
static Foo inst; // uninitialized - zero
static guard instGuard; // zero
if (is_initialized(instGuard) == false)
{
__cxa_guard_acquire(instGuard);
// do the initialization here - calls Foo constructor
set_initialized(instGuard);
__cxa_guard_release(instGuard);
}
return inst;
}
Run Code Online (Sandbox Code Playgroud)
所以你的两个例子都是线程安全的.