zoukankan      html  css  js  c++  java
  • ACE vs Boost: Singleton的实现

    以前曾经讨论过Singleton的实现,这次在对照ACE和Boost代码的时候,又重新审视了一下二者对Singleton不同的实现。其间的差别也体现了不同的编程哲学:ACE的实现更加偏重多线程中的安全和效率问题;Boost的实现则偏重于使用语言自身的特性满足Singleton模式的基本需求。

    o ACE的实现

    Douglas C. Schmidt在Double-Checked Locking: An Optimization Pattern for Efficiently Initializing and Accessing Thread-safe Objects一文中对double-check lock(一般译为双检锁)进行了详细的阐述。

    ACE的Singleton使用Adapter模式实现对其他类的适配,使之具有全局唯一的实例。由于C++标准并非明确指定全局静态对象的初始化顺序,ACE使用double-check lock保证线程安全,并使之不受全局静态对象初始化顺序的影响,同时也避免了全局静态实现方式的初始化后不使用的开销。

    如果你能够准确的区分以下三种实现的弊端和隐患,对double-check lock也就有了足够的了解。

    // -------------------------------------------
    class Singleton
    {
    public:
        static Singleton *instance (void)
        {
            // Constructor of guard acquires
            // lock_ automatically.
            Guard<Mutex> guard (lock_);
            // Only one thread in the
            // critical section at a time.
            if (instance_ == 0)
                instance_ = new Singleton;
            return instance_;
            // Destructor of guard releases
            // lock_ automatically.
        }
    private:
        static Mutex lock_;
        static Singleton *instance_;
    };

    // ---------------------------------------------
    static Singleton *instance (void)
    {
        if (instance_ == 0) {
            Guard<Mutex> guard (lock_);
            // Only come here if instance_
            // hasn’t been initialized yet.
            instance_ = new Singleton;
        }
        return instance_;
    }

    // ---------------------------------------------
    class Singleton
    {
    public:
        static Singleton *instance (void)
        {
            // First check
            if (instance_ == 0)
            {
                // Ensure serialization (guard
                // constructor acquires lock_).
                Guard<Mutex> guard (lock_);
                // Double check.
                if (instance_ == 0)
                    instance_ = new Singleton;
            }
            return instance_;
            // guard destructor releases lock_.
        }
    private:
        static Mutex lock_;
        static Singleton *instance_;
    };

    更多详情,见Schmidt老师的原文和ACE_Singleton实现。

    o Boost的实现

    Boost的Singleton也是线程安全的,而且没有使用锁机制。当然,Boost的Singleton有以下限制(遵从这些限制,可以提高效率):

    o The classes below support usage of singletons, including use in program startup/shutdown code, AS LONG AS there is only one thread running before main() begins, and only one thread running after main() exits.

    o This class is also limited in that it can only provide singleton usage for classes with default constructors.

    // T must be: no-throw default constructible and no-throw destructible
    template <typename T>
    struct singleton_default
    {
    private:
        struct object_creator
        {
            // This constructor does nothing more than ensure that instance()
            //  is called before main() begins, thus creating the static
            //  T object before multithreading race issues can come up.
            object_creator() { singleton_default<T>::instance(); }
            inline void do_nothing() const { }
        };
        static object_creator create_object;

        singleton_default();

    public:
        typedef T object_type;

        // If, at any point (in user code), singleton_default<T>::instance()
        //  is called, then the following function is instantiated.
        static object_type & instance()
        {
            // This is the object that we return a reference to.
            // It is guaranteed to be created before main() begins because of
            //  the next line.
          static object_type obj;

          // The following line does nothing else than force the instantiation
          //  of singleton_default<T>::create_object, whose constructor is
          //  called before main() begins.
          create_object.do_nothing();

          return obj;
        }
    };
    template <typename T>
    typename singleton_default<T>::object_creator
    singleton_default<T>::create_object;

    对于多数Singleton使用,Boost提供的版本完全能够满足需求。为了效率,我们有必要对其使用作出一定的限制。

    而在多线程编程中,则有必要使用double-check lock降低频繁加锁带来的开销。

  • 相关阅读:
    解决粘包问题
    粘包问题
    模拟ssh功能
    套接字接上链接循环
    套接字加入通讯循环
    简单通信
    网络编程
    单例模式
    记录一下:chrome上,把网页保存为文件的插件
    centos6.5 64bit 实现root开机自动登录X桌面
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318938.html
Copyright © 2011-2022 走看看