(代码取自书籍: http://gameprogrammingpatterns.com/ 作者:Robert Nystrom)
在上面的书中,作者提供了两种不同的创建单例类的方法:
第一个:
class FileSystem
{
public:
static FileSystem& instance()
{
// Lazy initialize.
if (instance_ == NULL) instance_ = new FileSystem();
return *instance_;
}
private:
FileSystem() {}
static FileSystem* instance_;
};
第二个:
class FileSystem
{
public:
static FileSystem& instance()
{
static FileSystem *instance = new FileSystem();
return *instance;
}
private:
FileSystem() {}
};
后来他指出第二个是更正确的方法,因为它是线程安全的,而第一个则不是。
是什么使第二个线程安全?
这两者之间的静态声明有什么区别?
最佳答案
第一个版本不是线程安全的,因为多个线程可能会尝试在没有任何同步的情况下同时读取和修改 instance_
,这会导致竞争条件。
自 C++11 起,第二个版本是线程安全的。引用自cppreference (静态局部变量部分):
If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once (similar behavior can be obtained for arbitrary functions with std::call_once)
有了这个保证,对实例
的修改只会发生一次,并且并发读取没有问题。
不过,在 C++11 之前,第二个版本并不是线程安全的。
关于c++ - 单例中静态声明之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29728910/