在我的C ++项目中,我有一个单例类。在项目执行期间,有时同时从两个不同的线程访问相同的单例类。导致生成单例类的两个实例,这是一个问题。
如何处理这类案件?
答案 0 :(得分:3)
然后它不是单身人士: - )
您可能需要向我们展示一些代码,但您的基本问题将是同步区域。
如果操作正确,则有 no 方式,两个线程可以创建该类的两个对象。实际上,这个类本身应该是强制执行单身性质的地方,以便错误的客户不会破坏意图。
基本结构将是:
lock mutex
if instance doesn't exist:
instance = new object
unlock mutex
如果没有互斥保护(或关键代码部分或任何其他方式,您可以保证语言/库级别的 ,两个线程无法同时运行代码),则有可能在检查和实例化之间可以换出一个线程,导致你的“单例”的两个可能的实例。
而且,正如其他人毫无疑问的那样,单身人士可能是一个坏主意。我不是在每个使用错误的营地,通常的问题是人们将它们视为“上帝”的对象。他们可以使用它们,但通常有更好的方法,但我不会假设你需要改变它,因为我不知道你的用例。
答案 1 :(得分:1)
如果你在不同的线程中得到两个不同的实例,那么你做错了什么。与进程不同,线程共享内存。因此,在一个线程中分配的内存(例如,对象实例)也可以在另一个线程中使用。
答案 2 :(得分:1)
如果您的单身人士获得两份副本,则不会使用互斥锁。获取/访问/设置内部对象时锁定互斥锁。
我相信你已经完成了这样的事情if(!_instance)_instance = new Singleton()
这里有一个关键的部分。你需要使用互斥锁来保护它。
答案 3 :(得分:1)
不要使用单身,这是众所周知的 Anti-Pattern
好读:
Singletons: Solving problems you didn’t know you never had since 1995
如果您仍然希望坚持并继续使用它,只有您自己知道的原因,您需要的是一个线程安全的单例实现,如下所示:
YourClass* YourClass::getInstance()
{
MutexLocker locker(YourClass::m_mutex);
if(!m_instanceFlag)
{
m_instance = new YourClass();
m_instanceFlag = true;
}
return m_instance;
}
其中MutexLocker
是常用互斥锁的包装类,它在创建实例时锁定互斥锁并解锁互斥锁,该函数结束。