C++ 九阴真经之线程安全单例类
与之前的单例类似,但普通的单例类是非线程安全的,就是是你不能有些线程读,有些线程写,一般来说,要安全访问单例,就需要用户自己加载来控制对单例的访问。
日常开发中经常会需要加载配置数据,我希望程序运行过程中能够定时的去更新这些配置信息,比如log级别,一般情况下开启INFO级别即可,但处理问题时,我希望打印DEBUG Log。
为了方便起见,这里实现一个线程安全单例,以便以后的项目能够快速的处理这种场景。
代码实现:
//哨兵类,负责多线程操作,自动加锁解锁
//哨兵类不允许拷贝,
template<typename T>
class SingletonGuard : std::unique_lockstd::mutex, public noncopyable
{
public:
explicit SingletonGuard(T* inst, std::mutex& mt):std::unique_lockstd::mutex(mt),m_guardPtr(inst)
{
}
SingletonGuard(SingletonGuard<T>&& guard) :m_guardPtr(guard.m_guardPtr)
{
guard.m_guardPtr = nullptr;
}
T* operator->()const
{
return m_guardPtr;
}
private:
T* m_guardPtr;
};
//线程安全单例
template<typename T>
class SingletonSafe : public noncopyable
{
public:
static SingletonGuard<T> get_mutable_instance(){
return SingletonGuard<T>(&get_instance(), m_signalMutex);
}
static const T & get_const_instance(){
return get_instance();
}
private:
static T & instance;
static void do_nothing(T const &) {}
static T & get_instance() {
static T ins;
do_nothing(instance);
return ins;
}
static std::mutex m_signalMutex;
};
template<typename T>
std::mutex SingletonSafe< T >::m_signalMutex;
template<typename T>
T & SingletonSafe< T >::instance = SingletonSafe< T >::get_instance();