从两个不同的线程同时第一次访问singleton类
Simultaneous first time access of singleton class from two different threads
在我的C++项目中,我有一个singleton类。在项目执行期间,有时从两个不同的线程同时访问同一个singleton类。导致生成了singleton类的两个实例,这是一个问题。
如何处理这样的案件?
那么它不是单例:-)
您可能需要向我们展示一些代码,但您的基本问题是同步区域。
如果做得好,两个线程可以创建类的两个对象的方式就不存在了。事实上,类本身应该是强制执行singleton特性的地方,这样错误的客户端就不会破坏意图。
基本结构为:
lock mutex
if instance doesn't exist:
instance = new object
unlock mutex
如果没有互斥锁保护之类的东西(或者关键代码段,或者任何其他可以在语言/库级别保证两个线程不能同时运行代码的方式),线程一可能会在检查和实例化之间交换,从而导致两个可能的"单例"实例。
而且,正如其他人无疑会暗示的那样,单身很可能是个坏主意。我不太喜欢每一次的使用都是错误的,通常的问题是人们把它们当作"上帝"的物体。它们可以有自己的用途,但通常有更好的方法,尽管我不会冒昧地告诉你你需要更改,因为我不知道你的用例。
如果在不同的线程中获得两个不同的实例,则说明您做错了什么。与进程不同,线程共享它们的内存。因此,在一个线程中分配的内存(例如,为对象实例分配的内存)也可用于另一个线程。
如果您的单例获得两个副本,那么它就没有用互斥锁保护。获取/访问/设置内部对象时锁定互斥对象。
我相信你做了这样的事情if(!_instance)_instance = new Singleton()
有一个关键部分。你需要用互斥锁来保护它。
不要使用singleton,它是众所周知的反模式
一本好书:
辛格尔顿:解决自1995年以来从未遇到过的问题
如果你仍然想坚持并继续它,原因只有你自己知道,你需要的是一个线程安全的单例实现,比如这样的:
YourClass* YourClass::getInstance()
{
MutexLocker locker(YourClass::m_mutex);
if(!m_instanceFlag)
{
m_instance = new YourClass();
m_instanceFlag = true;
}
return m_instance;
}
其中MutexLocker
是通常使用的互斥体的包装类,它在创建其实例时锁定互斥体,并解锁互斥体,函数结束。
- 唤醒多个线程以在每个条件下工作一次
- 我需要线程函数在不停止实际程序的情况下,每2秒打印一次随机数
- Qt不能多次执行线程
- E/libEGL:调用没有当前上下文的 OpenGL ES API (每个线程记录一次) - Android/SDL
- 使用互斥锁将一次运行的线程数限制为 2
- 当实例化两次时,C 提升线程会导致分割故障
- 在 C Linux 中使用三个线程使用信号量同步按顺序打印 3 4 5 50 次
- 必须将 std::thread 加入 std::vector<std::thread> 两次以避免从线程 dtor 终止
- 函数作用域是静态变量还是线程本地变量在C++11中的第一个条目中初始化
- 构造函数在不同线程中的静态单例类上调用两次
- 如何使一个线程按预期顺序多次等待另一个线程
- 如何在同一个线程上用同一个互斥对象锁定两次
- 如果我确定只有一个线程一次处理指针/对象,则C/C 仍应使用同步
- OpenMP 一次只执行一个线程
- 为什么我的单例实现两次启动?(一个进程,多个线程)
- 线程仅执行一次
- 如何依次多次调用3个线程
- 从两个不同的线程同时第一次访问singleton类
- WaitForSingleObject - 每个线程一次
- c++多线程:一次只保持一个线程(除了主线程)活动