面试题目整理 线程安全的单例模式

首先看看boost 的单例模式 

boost/thread/detail/singleton.hpp

template <class T>
class singleton : private T
{
private:
    singleton();
    ~singleton();


public:
    static T &instance();
};
template <class T>
inline singleton<T>::singleton()
{
    /* no-op */
}
template <class T>
inline singleton<T>::~singleton()
{
    /* no-op */
}
template <class T>
/*static*/ T &singleton<T>::instance()
{
    // function-local static to force this to work correctly at static
    // initialization time.
    static singleton<T> s_oT;
    return(s_oT);
}
单例在首次调用访问时产生 非线程安全

@ boost/container/detail/singleton.hpp

// 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;

重要的是这句:

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

保证单例在main() 之前生成

类似的设计在boost还有,

再来一个陈硕的 singleton 

template<typename T>
class Singleton : boost::noncopyable
{
 public:
  static T& instance()
  {
    pthread_once(&ponce_, &Singleton::init);
    assert(value_ != NULL);
    return *value_;
  }


 private:
  Singleton();
  ~Singleton();


  static void init()
  {
    value_ = new T();
    if (!detail::has_no_destroy<T>::value)
    {
      ::atexit(destroy);
    }
  }


  static void destroy()
  {
    typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
    T_must_be_complete_type dummy; (void) dummy;


    delete value_;
    value_ = NULL;
  }


 private:
  static pthread_once_t ponce_;
  static T*             value_;
};


template<typename T>
pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;


template<typename T>
T* Singleton<T>::value_ = NULL;

使用pthread_once 保证init 只执行一次


c++ 11 的 call_once 

template< class Function, class... Args >  
void call_once ( std::once_flag& flag, Function&& f, Args&& args... );  
参数解析Parameters:  
flag     -   an object, for which exactly one function gets executed  
f     -   需要被调用的函数  
args...  -   传递给函数f的参数(可以多个)  
返回值为 (none)  
抛出异常  
std::system_error if any condition prevents calls to call_once from executing as specified any exception thrown by f

使用 所以我们能使用 call_once 函数实现一个 跨平台的singleton

首先拷贝 boost nocopyable

class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private:  // emphasize the following members are private 
noncopyable(const noncopyable&);
const noncopyable& operator=(const noncopyable&);
};
template<typename T>
class Singleton : public noncopyable
{
public:
static T& instance()
{
call_once(ponce_, &Singleton::init);
return *value_;
}
private:
static void init()
{
value_ = new T();
}
private:
static std::once_flag ponce_;
static T*             value_;
};
template<typename T>
std::once_flag Singleton<T>::ponce_ ;
template<typename T>
T* Singleton<T>::value_ = nullptr;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值