以下实现,使用延迟初始化Singleton(Meyers'Seingleton)线程安全吗?
static Singleton& instance()
{
static Singleton s;
return s;
}
Run Code Online (Sandbox Code Playgroud)
如果没有,为什么以及如何使其线程安全?
这个问题让我质疑我多年来一直遵循的做法.
对于函数本地静态const对象的线程安全初始化,我保护对象的实际构造,但不保护引用它的函数本地引用的初始化.像这样的东西:
namespace {
const some_type& create_const_thingy()
{
lock my_lock(some_mutex);
static const some_type the_const_thingy;
return the_const_thingy;
}
}
void use_const_thingy()
{
static const some_type& the_const_thingy = create_const_thingy();
// use the_const_thingy
}
Run Code Online (Sandbox Code Playgroud)
这个想法是锁定需要时间,如果引用被多个线程覆盖,那么无关紧要.
如果是的话,我会感兴趣的
我想知道这个的原因是我想知道我是否可以保留代码,或者我是否需要回去修复它.
对于探究的头脑:
我使用的许多这样的函数本地静态const对象是在首次使用时从const数组初始化并用于查找的映射.例如,我有一些XML解析器,其中标记名称字符串映射到enum值,因此我可以稍后switch覆盖标记的enum值.
由于我得到了一些关于该做什么的答案,但是没有得到我实际问题的答案(见上文1.和2.),我会对此开始赏金.还是那句话:
我不感兴趣,我能做什么,而不是,我真的想知道这个.
方法1
DataCenter* DataCenter::getInstance()
{
static DataCenter instance;
return &instance;
}
Run Code Online (Sandbox Code Playgroud)
方法2
DataCenter* DataCenter::getInstance()
{
if (!m_instanceFlag)
{
m_instance = new DataCenter();
m_instanceFlag = true;
}
return m_instance;
}
Run Code Online (Sandbox Code Playgroud)
我正在进行多线程编程,DataCenter将由多个线程访问.我曾经有方法2来获取DataCenter的实例,它工作正常.但我注意到我需要保护单例实例不被多线程调用.
我的问题是,我真的需要保护单例实例吗?或OS是否为我这样做?第二个问题是,第一种方法是获得单例实例的正确方法吗?
提前致谢...
采用这个简单的函数,在由std::mutex以下实现的锁定下递增整数:
#include <mutex>
std::mutex m;
void inc(int& i) {
std::unique_lock<std::mutex> lock(m);
i++;
}
Run Code Online (Sandbox Code Playgroud)
我希望这(在内联之后)以直接的方式编译,然后调用m.lock()增量.im.unlock()
检查生成的程序集的最新版本的gcc和clang,但是,我们看到一个额外的并发症.gcc首先考虑版本:
inc(int&):
mov eax, OFFSET FLAT:__gthrw___pthread_key_create(unsigned int*, void (*)(void*))
test rax, rax
je .L2
push rbx
mov rbx, rdi
mov edi, OFFSET FLAT:m
call __gthrw_pthread_mutex_lock(pthread_mutex_t*)
test eax, eax
jne .L10
add DWORD PTR [rbx], 1
mov edi, OFFSET FLAT:m
pop rbx
jmp __gthrw_pthread_mutex_unlock(pthread_mutex_t*)
.L2:
add DWORD PTR [rdi], 1
ret
.L10:
mov edi, eax …Run Code Online (Sandbox Code Playgroud) 这个单例线程对于前C++ 11编译器是否安全?正如我们对C++ 11所知,它是线程安全的.
class Singleton
{
private:
Singleton(){};
public:
static Singleton& instance()
{
static Singleton INSTANCE;
return INSTANCE;
}
};
Run Code Online (Sandbox Code Playgroud)