本文主要是介绍tars源码漫谈第28篇------tc_singleton.h(多线程下的单例),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
要写一个单例, 很简单。 但是, 如果考虑多线程, 还真不是容易的事, 来看看tc_singleton.h:
/*** Tencent is pleased to support the open source community by making Tars available.** Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.** Licensed under the BSD 3-Clause License (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at** https://opensource.org/licenses/BSD-3-Clause** Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License.*/#ifndef __TC_SINGLETON_H__
#define __TC_SINGLETON_H__#include "util/tc_monitor.h"
#include <cassert>
#include <cstdlib>namespace tars
{
/
/** * @file tc_singleton.h * @brief 单件类 . * * 单件实现类* * 没有实现对单件生命周期的管理,使用示例代码如下:* * class A : public TC_Singleton<A, CreateStatic, DefaultLifetime>* * {* * public:* * A(){cout << "A" << endl;}* * ~A()* * {* * cout << "~A" << endl;* * * }** void test(){cout << "test A" << endl;}* * };* 对象的创建方式由CreatePolicy指定, 有如下方式:* * CreateUsingNew: 在堆中采用new创建* * CreateStatic`: 在栈中采用static创建* * 对象生命周期管理由LifetimePolicy指定, 有如下方式:* * DefaultLifetime:缺省声明周期管理* *如果单件对象已经析够, 但是还有调用, 会触发异常 * * PhoneixLifetime:不死生命周期* * 如果单件对象已经析够, 但是还有调用, 会再创建一个* * NoDestroyLifetime:不析够* * 对象创建后不会调用析够函数析够, 通常采用实例中的方式就可以了**/
//*** @brief 定义CreatePolicy:定义对象创建策略*/
template<typename T>
class CreateUsingNew
{
public:/*** @brief 创建.* * @return T**/static T* create() { return new T; }/*** @brief 释放. * * @param t*/static void destroy(T *t) { delete t; }
};template<typename T>
class CreateStatic
{
public:/*** @brief 最大的空间*/ union MaxAlign { char t_[sizeof(T)]; long double longDouble_; }; /*** @brief 创建. * * @return T**/static T* create() { static MaxAlign t; return new(&t) T; }/*** @brief 释放. * * @param t*/static void destroy(T *t) {t->~T();}
};/*** @brief 定义LifetimePolicy:定义对象的声明周期管理*/
template<typename T>
class DefaultLifetime
{
public:static void deadReference(){throw std::logic_error("singleton object has dead.");}static void scheduleDestruction(T*, void (*pFun)()){std::atexit(pFun);}
};template<typename T>
class PhoneixLifetime
{
public:static void deadReference(){_bDestroyedOnce = true;}static void scheduleDestruction(T*, void (*pFun)()){if(!_bDestroyedOnce)std::atexit(pFun);}
private:static bool _bDestroyedOnce;
};
template <class T>
bool PhoneixLifetime<T>::_bDestroyedOnce = false; template <typename T>
struct NoDestroyLifetime
{ static void scheduleDestruction(T*, void (*)()) {} static void deadReference() {}
}; //
// Singleton
template
<typename T,template<class> class CreatePolicy = CreateUsingNew,template<class> class LifetimePolicy = DefaultLifetime
>
class TC_Singleton
{
public:typedef T instance_type;typedef volatile T volatile_type;/*** @brief 获取实例* * @return T**/static T *getInstance(){//加锁, 双check机制, 保证正确和效率if(!_pInstance){TC_ThreadLock::Lock lock(_tl);if(!_pInstance){if(_destroyed){LifetimePolicy<T>::deadReference();_destroyed = false;}_pInstance = CreatePolicy<T>::create();LifetimePolicy<T>::scheduleDestruction((T*)_pInstance, &destroySingleton);}}return (T*)_pInstance;}virtual ~TC_Singleton(){}; protected:static void destroySingleton(){assert(!_destroyed);CreatePolicy<T>::destroy((T*)_pInstance);_pInstance = NULL;_destroyed = true;}
protected:static TC_ThreadLock _tl;static volatile T* _pInstance;static bool _destroyed;protected:TC_Singleton(){}TC_Singleton (const TC_Singleton &); TC_Singleton &operator=(const TC_Singleton &);
};template <class T, template<class> class CreatePolicy, template<class> class LifetimePolicy>
TC_ThreadLock TC_Singleton<T, CreatePolicy, LifetimePolicy>::_tl; template <class T, template<class> class CreatePolicy, template<class> class LifetimePolicy>
bool TC_Singleton<T, CreatePolicy, LifetimePolicy>::_destroyed = false; template <class T, template<class> class CreatePolicy, template<class> class LifetimePolicy>
volatile T* TC_Singleton<T, CreatePolicy, LifetimePolicy>::_pInstance = NULL; }#endif
写得够风骚。如果没太读懂, 也没什么关系, 后面主要是单例的使用。
如果有必要看多线程单例的具体细节, 再看。
这篇关于tars源码漫谈第28篇------tc_singleton.h(多线程下的单例)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!