• (七)boost库之单例类


    (七)boost库之单例类

        一、boost.serialzation的单件实现

        单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

        单例,通常在一个大型项目中单例是非常常见的,boost库没有提供专门的单例类,但可以在其它库中找到他的实现

    #include <boost/serialization/singleton.hpp> 
    
    class ThreadPoll : public boost::serialization::singleton<ThreadPoll>
    
    {
    
    
    
    };
    

    当然,你也可以不使用继承的方式,只需要typedef一下,就可以得到一个全局访问点,这种方式会更加的灵活。

    class ThreadPoll
    
    {
    
    
    
    };
    
    typedef boost::serialization::singleton<ThreadPoll> ThreadPollAgent;
    

    但是,该单例是非线程安全的,单件类实现了一个全局访问点,如果在多个线程环境中访问,是需要自行加锁的,因此,如果需要一个线程安全的单件,需要自己实现。

    二、自行实现线程安全单件

    /******************************************************
    
    * 支持线程安全的单例类
    
    *******************************************************/
    
    
    
    #ifndef __SINGLETON_H__
    
    #define __SINGLETON_H__
    
    
    
    #include <boost/noncopyable.hpp>
    
    #include <boost/thread.hpp>
    
    
    
    //哨兵类,负责多线程操作,自动加锁解锁
    
    //哨兵类不允许拷贝,
    
    template<typename T>
    
    class SingletonGuard : boost::mutex::scoped_lock, public boost::noncopyable
    
    {
    
    public:
    
        explicit SingletonGuard(T* inst, boost::mutex& mt):boost::mutex::scoped_lock(mt),m_guardPtr(inst)
    
        {         
    
        }
    
        T* operator->()
    
        {
    
            return m_guardPtr;
    
        }
    
    private:
    
        T* m_guardPtr;
    
    };
    
    
    
    //监视类,用于监视单例的状态
    
    template<typename T>
    
    class Singleton_wrapper : public T
    
    {
    
    public:
    
        static bool m_is_destroyed;
    
        ~Singleton_wrapper(){
    
            m_is_destroyed = true;
    
        }
    
    };
    
    
    
    template<typename T>
    
    bool Singleton_wrapper< T >::m_is_destroyed = false;
    
    
    
    //单例
    
    template<typename T>
    
    class Singleton : public boost::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 use(T const &) {}
    
        static T & get_instance() {
    
            static Singleton_wrapper< T > t;
    
            //编译期进行初始化实例
    
            BOOST_ASSERT(! Singleton_wrapper< T >::m_is_destroyed);
    
            use(instance);
    
            return static_cast<T &>(t);
    
        }
    
        static boost::mutex m_signalMutex; 
    
    protected:
    
        boost::mutex::scoped_lock ScopedLock()
    
        {
    
            return boost::mutex::scoped_lock(m_signalMutex);
    
        }
    
    };
    
    template<typename T>
    
    boost::mutex Singleton< T >::m_signalMutex; 
    
    
    
    template<typename T>
    
    T & Singleton< T >::instance = Singleton< T >::get_instance();
    
    
    
    #endif //__SINGLETON_H__

    该类参考boost单件的实现,使用上相似,但get_mutable_instance返回的不是实例对象,而是保存该实例指针的一个临时变量,通过定义->符号访问实例的函数,离开该作用域时,临时变量析构,

    自行解锁。通过该单例访问的所有函数都将已加锁的形式进行访问,如果想在不加锁的情况下访问,只能通过get_const_instance获取实例的方式访问。

    你可以像下面这样使用:

    class ThreadPoll
    
    {
    
    public:
    
        void Update(){};
    
        int Query()const{};
    
    };
    
    typedef Singleton<ThreadPoll> ThreadPollAgent;
    
    ThreadPollAgent::get_mutable_instance()->Update();
    
    ThreadPollAgent::get_const_instance().Query();
  • 相关阅读:
    tomcat 调优-生产环境必备
    Spring中 BeanFactory和ApplicationContext的区别
    延迟队列DelayQueue简单入门
    RedisTemplate中opsForValue的使用 (复制粘贴的,没有练习,找时间回顾 )
    yum安装nginx的默认目录详解
    Centos 6无法使用yum解决办法
    JVM:jmap heap 堆参数分析MinHeapFreeRatio、MaxHeapFreeRatio、MaxHeapSize、NewSize、MaxNewSize
    maven下载Oracle jar包
    idea查看源代码出现/* compiled code */
    今日进度
  • 原文地址:https://www.cnblogs.com/timssd/p/5544677.html
Copyright © 2020-2023  润新知