2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > C++ 多线程下的单例模式

C++ 多线程下的单例模式

时间:2018-09-07 08:33:20

相关推荐

C++ 多线程下的单例模式

/*代码中经常会使用到单例模式,单例模式就是隐藏构造函数,提供获取一个实例的静态方法。但是在多线程场景下,单例模式会有一些不同。例如Config类的instance方法如下*///获取一个实例(对外接口)static Config * instance(){if (NULL == m_instance){//加锁(多线程场景下) m_mutex.acquire();if (NULL == m_instance){m_instance = new Config();/*类似于这个类的初始化,我是不建议放在这里的,因为如果init方法执行失败,但是实例仍然不为NULL,建议在main函数中第一次调用instance方法时,执行init方法初始化实例(注意init方法也是只能执行一次的,请考虑多线程场景)init方法放在这个纯粹是为了解释这个场景下单例的使用*/m_instance->init();}//解锁 m_mutex.release();}return m_instance;}

/*如果在instance方法中不加锁,在多线程的场景下,有可能创建出多个实例。instance方法在加锁之后,还是有问题的。假设线程A正在执行m_instance->init()方法(init方法执行的时间很长),此时线程B开始执行instance方法,发现m_instance != NULL(因为线程A已经构造了该实例),那么线程B就会直接获取到这个并没有执行完init方法的m_instance实例,线程B用这个m_instance去执行操作,就会出现问题。*/

/*简单的改进就是,去掉前边的判断,直接加锁,这样就避免了该问题,线程B进行进来的时候因为线程A已经获取到锁,线程B会等待,等到线程A释放锁之后(所有初始化操作已经完成),线程B判断m_instance != NULL,线程B可以使用m_instance这个实例了*/static Config * Config::instance(){//加锁(多线程场景下) m_mutex.acquire();if (NULL == m_instance){m_instance = new Config();m_instance->init();}//解锁 m_mutex.release();

return m_instance;}

/*但是这样的改进会出现一个新问题,就是每次调用这个单例就会加锁判断,频繁调用会影响速度*/

/*再次改进方案,使用一个临时变量构造,初始化,成功后再赋值给m_instance这样避免了多线程操作影响,又不影响速度*/static Config * instance(){if (NULL == m_instance){//加锁(多线程场景下) m_mutex.acquire();if (NULL == m_instance){Config * pInstance = new Config();pInstance->init();m_instance = pInstance;}//解锁 m_mutex.release();}return m_instance;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。