gpt4 book ai didi

c++ - C++11 中的线程安全单例

转载 作者:太空狗 更新时间:2023-10-29 19:43:27 25 4
gpt4 key购买 nike

我知道以下是在 C++11 中实现单例的线程安全方式:

Foo* getInst()
{
static Foo* inst = new Foo(...);
return inst;
}

我读入了this answer以下内容也是线程安全的:

Foo& getInst()
{
static Foo inst(...);
return inst;
}

真的是线程安全的吗?
Foo的实例 会在单个栈帧中分配 不会在堆上分配,这不是问题吗?

如果它是线程安全的,是否有充分的理由更喜欢其中之一?

最佳答案

静态变量分配在堆栈上。在第一个变体中,您有一个静态指针(一个全局变量),它使用从堆中获得的内存进行初始化,而在第二个变体中,您有整个静态对象。

两个版本都使用内部编译器保护(即 __cxa_guard_acquire()__cxa_guard_release(),它们在功能上等同于 mutex::lock()mutex::unlock()) 以确保序列化访问一个特殊变量,该变量指示您的全局实例是否已经初始化。

您的代码:

Foo& getInst()
{
static Foo inst(...);
return inst;
}

编译后实际上看起来像这样:

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;
}

所以你的两个例子都是线程安全的。

关于c++ - C++11 中的线程安全单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26955001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com