使用l临界区来实现单例模式
来源:互联网 发布:ubuntu如何安装输入法 编辑:程序博客网 时间:2024/06/13 14:22
#include <stdlib.h>
#include <Windows.h>
class Mutex {
public:
Mutex() { InitializeCriticalSection(§ion); }
~Mutex() { DeleteCriticalSection(§ion); }
void Enter() { EnterCriticalSection(§ion); }
void Leave() { LeaveCriticalSection(§ion); }
struct Lock;
Mutex(const Mutex&);
Mutex& operator=(const Mutex&);
protected:
CRITICAL_SECTION section;
};
struct Mutex::Lock {
Mutex& s;
Lock(Mutex& s):s(s) { s.Enter(); }
~Lock() { s.Leave(); }
};
template<typename T, typename LOCK>
class HySingleton
{
public:
static T* Instance()
{
if (!m_pInstance)
{
MakeInstance();
}
return m_pInstance;
}
private:
/************************************************************************
Singleton这个类本身是一个永远不会被实例化的类,所以没有构造和析构调用
这里确保“析构函数”被调用,其实现手法和编译器处理析构函数很类似
确保程序退出的时候T的析构函数被调用,并且执行相关清理动作
************************************************************************/
static void MakeInstance()
{
//在这里加入多线程保护,TODO
//这里采用"双检测锁定",在调用MakeInstance之前已经检查过一次了
//LOCK::HyAutoLock _lock(m_lock);
Mutex::Lock _lock(m_lock);
if (!m_pInstance)
{
if(m_bDestroyed)
{
//Dead Reference Detected
OnDeadReference();
//OnDeadReference()没有抛出异产的话
//对象就会"复活"
m_bDestroyed = false;
}
m_pInstance = new T;
//每次new完后,要确保delete
atexit(DestroySingleton);
}
}
/************************************************************************
如果在程序结束时,单体内的静态成员已经析构。
有另一个寿命更长的对象访问这个单体,就会出现引用失效。
因为谁也不知道编译按什么顺序销毁对象(好像是先生成的后销毁,即atexit以stack方式运作,见MSDN和C++方案)。
************************************************************************/
/************************************************************************
让对象销毁
************************************************************************/
static void DestroySingleton()
{
if(m_bDestroyed)
{
throw ("Singleton has been destroyed!");
}
//销毁T的实例
delete m_pInstance;
//设置状态
m_pInstance = NULL;
m_bDestroyed = true;
}
/************************************************************************
当检测到调用已经销毁的对象时,调用该函数
************************************************************************/
static void OnDeadReference()
{
//这里什么都不做可以让已经被销毁的静态成员变量复活
//但是对于状态复杂的对象,单实例化是不足以使对象工作的
//而且这里好像没有办法插入T所需要的初始化代码,因为这个时候程序正在结束中
//所以也可以抛出异常结束程序
// throw std::runtime_error("Dead Reference Detected");
}
static T* m_pInstance;
static bool m_bDestroyed;
static LOCK m_lock;
};
template<typename T, typename LOCK> T* HySingleton<T, LOCK>::m_pInstance = NULL;
template<typename T, typename LOCK> bool HySingleton<T, LOCK>::m_bDestroyed = false;
template<typename T, typename LOCK> LOCK HySingleton<T, LOCK>::m_lock;
#define USE_SINGLETON template<typename T,typename LOCK> friend class HySingleton;
class MyClass
//: public HySingleton<MyClass,Mutex>
{
public:
//friend class HySingleton<MyClass,Mutex>;
USE_SINGLETON
MyClass(){};
~MyClass(){};
void Print() { printf("testing %d\n",val); }
int val;
};
#define GetDeviceDefinePtr() HySingleton<MyClass,Mutex>::Instance()
int _tmain(int argc, _TCHAR* argv[])
{
HySingleton<MyClass,Mutex>::Instance()->val=9;
GetDeviceDefinePtr()->Print();
return 0;
}
#include <Windows.h>
class Mutex {
public:
Mutex() { InitializeCriticalSection(§ion); }
~Mutex() { DeleteCriticalSection(§ion); }
void Enter() { EnterCriticalSection(§ion); }
void Leave() { LeaveCriticalSection(§ion); }
struct Lock;
Mutex(const Mutex&);
Mutex& operator=(const Mutex&);
protected:
CRITICAL_SECTION section;
};
struct Mutex::Lock {
Mutex& s;
Lock(Mutex& s):s(s) { s.Enter(); }
~Lock() { s.Leave(); }
};
template<typename T, typename LOCK>
class HySingleton
{
public:
static T* Instance()
{
if (!m_pInstance)
{
MakeInstance();
}
return m_pInstance;
}
private:
/************************************************************************
Singleton这个类本身是一个永远不会被实例化的类,所以没有构造和析构调用
这里确保“析构函数”被调用,其实现手法和编译器处理析构函数很类似
确保程序退出的时候T的析构函数被调用,并且执行相关清理动作
************************************************************************/
static void MakeInstance()
{
//在这里加入多线程保护,TODO
//这里采用"双检测锁定",在调用MakeInstance之前已经检查过一次了
//LOCK::HyAutoLock _lock(m_lock);
Mutex::Lock _lock(m_lock);
if (!m_pInstance)
{
if(m_bDestroyed)
{
//Dead Reference Detected
OnDeadReference();
//OnDeadReference()没有抛出异产的话
//对象就会"复活"
m_bDestroyed = false;
}
m_pInstance = new T;
//每次new完后,要确保delete
atexit(DestroySingleton);
}
}
/************************************************************************
如果在程序结束时,单体内的静态成员已经析构。
有另一个寿命更长的对象访问这个单体,就会出现引用失效。
因为谁也不知道编译按什么顺序销毁对象(好像是先生成的后销毁,即atexit以stack方式运作,见MSDN和C++方案)。
************************************************************************/
/************************************************************************
让对象销毁
************************************************************************/
static void DestroySingleton()
{
if(m_bDestroyed)
{
throw ("Singleton has been destroyed!");
}
//销毁T的实例
delete m_pInstance;
//设置状态
m_pInstance = NULL;
m_bDestroyed = true;
}
/************************************************************************
当检测到调用已经销毁的对象时,调用该函数
************************************************************************/
static void OnDeadReference()
{
//这里什么都不做可以让已经被销毁的静态成员变量复活
//但是对于状态复杂的对象,单实例化是不足以使对象工作的
//而且这里好像没有办法插入T所需要的初始化代码,因为这个时候程序正在结束中
//所以也可以抛出异常结束程序
// throw std::runtime_error("Dead Reference Detected");
}
static T* m_pInstance;
static bool m_bDestroyed;
static LOCK m_lock;
};
template<typename T, typename LOCK> T* HySingleton<T, LOCK>::m_pInstance = NULL;
template<typename T, typename LOCK> bool HySingleton<T, LOCK>::m_bDestroyed = false;
template<typename T, typename LOCK> LOCK HySingleton<T, LOCK>::m_lock;
#define USE_SINGLETON template<typename T,typename LOCK> friend class HySingleton;
class MyClass
//: public HySingleton<MyClass,Mutex>
{
public:
//friend class HySingleton<MyClass,Mutex>;
USE_SINGLETON
MyClass(){};
~MyClass(){};
void Print() { printf("testing %d\n",val); }
int val;
};
#define GetDeviceDefinePtr() HySingleton<MyClass,Mutex>::Instance()
int _tmain(int argc, _TCHAR* argv[])
{
HySingleton<MyClass,Mutex>::Instance()->val=9;
GetDeviceDefinePtr()->Print();
return 0;
}
0 0
- 使用l临界区来实现单例模式
- 使用枚举来实现单例模式
- 使用宏来实现单例模式
- 使用MFC的CCriticalSection类来实现操作临界区
- 用户枚举来实现单例模式
- 使用缓存来模拟实现单例
- 用枚举类型来实现单例模式
- C++使用临界区实现进程同步
- 使用临界区 CRITICAL_SECTION 实现互斥
- C++使用临界区来控制多线程访问同一个变量
- C++使用临界区来控制多线程访问同一个变量
- 单例模式来咯!
- C++ 使用模板 实现单例模式
- 使用单例模式实现mysql类
- 使用dispatch_once实现单例模式
- 使用dispatch_once实现单例模式
- C++ 使用模板实现单例模式
- iOS--使用GCD实现单例模式
- Oracle 12c Windows安装、介绍及简单使用(图文)
- 个人总结——app应用程序签名
- HttpClient使用详解
- Cocos Creator 访问节点和组件(摘自官方文档)
- TFS入门使用教程--新建团队项目
- 使用l临界区来实现单例模式
- c++在linux下读取文件遇到的问题
- yaffs2移植到内核linux-4.4.16的修改记录
- 并查集 POJ 1703
- C#抽象类和接口的区别分析
- 【Linux学习】epoll详解
- oracle 查找4000字节以下的记录
- URL参数中&和+被转成空格
- Django 分页