Qt中实现单例模式(SingleTon)
单例模式分为“饥汉”和“饿汉”两种版本,也正是线程安全问题使得原本简单的单例模式变得复杂。由于单例模式很常用,Boost库中有强大的泛型单例实现,我也利用Qt的原子指针QAtomicPointer来实现Qt中的单例模式:

//.cpp
class SingleTon
{

public:
/*! \brief 用于获得SingleTon实例,使用单例模式。
* \return SingleTon实例的引用。
*/
static SingleTon &getInstance(void)
{
//使用双重检测。

if(!instance)//第一次检测
{
QMutexLocker locker(&mutex);//加互斥锁。

if(!instance)//第二次检测。
instance = new SingleTon;
}

return *instance;
}

private:
SingleTon();//禁止构造函数。
SingleTon(const SingleTon &);//禁止拷贝构造函数。
SingleTon & operator=(const SingleTon &);//禁止赋值拷贝函数。

QReadWriteLock internalMutex;//函数使用的读写锁。

static QMutex mutex;//实例互斥锁。
static QAtomicPointer<SingleTon> instance;/*!<使用原子指针,默认初始化为0。*/
};
//静态成员变量初始化。
QMutex SingleTon::mutex;
QAtomicPointer<SingleTon> SingleTon::instance = 0;
双重锁检测在C++中是安全的,另外提供了读写锁,在修改单例数据的函数中使用写锁(QWriteLocker locker(&internalMutex););在读取单例数据的函数中使用读锁(QReadLocker locker(&internalMutex);)。

之前没考虑到乱序执行问题,并且此前代码有严重BUG,即对QAtomicPointer类型变量赋值操作不是原子操作,见官方文档:

For convenience, QAtomicPointer provides pointer comparison, cast, dereference, and assignment operators. Note that these operators are not atomic.

修改代码,使用testAndSetOrdered原子操作,并解决乱序执行问题,testAndSetOrdered特性:

This function uses ordered memory ordering semantics, which ensures that memory access before and after the atomic operation (in program order) may not be re-ordered.

其中关于memory ordering,我转过此帖:http://www.cnblogs.com/codingmylife/archive/2010/04/28/1722573.html

其中关于double checked locking,有此文:http://docs.huihoo.com/ace_tao/lifecycle.html

修改版SingleTon.cpp:

//.cpp 一次修改版
class SingleTon
{

public:
/*! \brief 用于获得SingleTon实例,使用单例模式。
* \return SingleTon实例的引用。
*/
static SingleTon &getInstance(void)
{

#ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
if(!QAtomicPointer::isTestAndSetNative())//运行时检测
qDebug() << "Error: TestAndSetNative not supported!";
#endif

//使用双重检测。

/*! testAndSetOrders操作保证在原子操作前和后的的内存访问
* 不会被重新排序。
*/
if(instance.testAndSetOrdered(0, 0))//第一次检测
{
QMutexLocker locker(&mutex);//加互斥锁。

instance.testAndSetOrdered(0, new SingleTon);//第二次检测。
}

return *instance;
}

private:
SingleTon();//禁止构造函数。
SingleTon(const SingleTon &);//禁止拷贝构造函数。
SingleTon & operator=(const SingleTon &);//禁止赋值拷贝函数。

QReadWriteLock internalMutex;//函数使用的读写锁。

static QMutex mutex;//实例互斥锁。
static QAtomicPointer<SingleTon> instance;/*!<使用原子指针,默认初始化为0。*/
};
欢迎大家拍砖!

http://www.cnblogs.com/codingmylife/archive/2010/07/14/1777409.html

看看 http://qt-project.org/wiki/Qt_thread-safe_singleton, 有很好的实现。

很久以前的文章了,实际上更Qt化的方法是直接用Q_GLOBAL_STATIC。

最新文章

  1. nodejs安装心得
  2. Spring-2-H Array Diversity(SPOJ AMR11H)解题报告及测试数据
  3. TabControl的SelectionChanged事件
  4. TOKEN+签名验证
  5. GitHub的实践
  6. IE浏览器-官网下载地址
  7. 各种HTML锚点跳转方式
  8. 【Bootstrap】优秀小插件收集
  9. 从零开始学习PYTHON3讲义(三)写第一个程序
  10. jQuery 对AMD的支持(Require.js中如何使用jQuery)
  11. ORACLE——NVL()、NVL2() 函数的用法
  12. 第一篇——Struts2的工作原理及HelloWorld简单实现
  13. MyBatis第一个案例-----永远的HelloWorld 含所有代码
  14. 【文件】使用word的xml模板生成.doc文件
  15. Ubuntu14.04 下软件安装和卸载命令备记
  16. openssl_error_string()
  17. 转)MySQL日期与时间函数
  18. Android-bindService本地服务-音乐播放-上
  19. 为什么在AI领域网络安全更重要?先睹为快~
  20. 应输入 #endregion 指令报错的排查技巧

热门文章

  1. 【38.24%】【codeforces 621E】 Wet Shark and Blocks
  2. Vue.JS学习基础
  3. unity3D 4.6与上述号码. UI穿透问题,而且不穿透的真机模拟器渗透问题解决
  4. shell问题集合
  5. 基于Web实现在线绘画拓扑图[GraphEditor]
  6. 取消Jquery mobile自动省略的文本
  7. Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮
  8. STL algorithm算法lexicographical_compare(30)
  9. Java异常处理错误
  10. POJ读书笔记2.1 —— 鸡兔笼带