从两个不同的线程同时第一次访问单例类

时间:2012-08-20 06:17:49

标签: c++

在我的C ++项目中,我有一个单例类。在项目执行期间,有时同时从两个不同的线程访问相同的单例类。导致生成单例类的两个实例,这是一个问题。

如何处理这类案件?

4 个答案:

答案 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是常用互斥锁的包装类,它在创建实例时锁定互斥锁并解锁互斥锁,该函数结束。