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();