高效的线程安全单例在C ++ [英] efficient thread-safe singleton in C++

查看:116
本文介绍了高效的线程安全单例在C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

单例类的通常模式是

  static Foo& getInst()
{
static Foo * inst = NULL;
if(inst == NULL)
inst = new Foo(...);
return * inst;但是,我的理解是,这个解决方案不是线程安全的,因为1是一个线程安全的, )Foo的构造函数可能被多次调用(可能或可能不重要)和2)在返回到不同的线程之前,inst可能无法完全构建。



一个解决方案是围绕整个方法包裹互斥,但是我付出的同步开销很长时间,我实际需要它。另一种是类似于

  static Foo& getInst()
{
static Foo * inst =空值;
if(inst == NULL)
{
pthread_mutex_lock(& mutex);
if(inst == NULL)
inst = new Foo(...);
pthread_mutex_unlock(& mutex);
}
return * inst;
}

这是正确的做法,还是有任何陷阱意识到?例如,是否存在可能发生的静态初始化顺序问题,即,第一次调用getInst时,inst始终保证为NULL?

解决方案


这个 www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf\">迈耶斯/ Alexandrescu论文解释了为什么 - 但是这篇论文也被广泛误解。它开始'双重锁定是不安全的C ++'模因 - 但它的实际结论是,双重检查锁定C ++可以安全地实现,它只是需要在一个非显而易见的地方使用内存障碍。



本文包含伪代码演示如何使用内存屏障来安全实现DLCP,因此您不应该难以纠正您的实现。


The usual pattern for a singleton class is something like

static Foo &getInst()
{
  static Foo *inst = NULL;
  if(inst == NULL)
    inst = new Foo(...);
  return *inst;    
}

However, it's my understanding that this solution is not thread-safe, since 1) Foo's constructor might be called more than once (which may or may not matter) and 2) inst may not be fully constructed before it is returned to a different thread.

One solution is to wrap a mutex around the whole method, but then I'm paying for synchronization overhead long after I actually need it. An alternative is something like

static Foo &getInst()
{
  static Foo *inst = NULL;
  if(inst == NULL)
  {
    pthread_mutex_lock(&mutex);
    if(inst == NULL)
      inst = new Foo(...);
    pthread_mutex_unlock(&mutex);
  }
  return *inst;    
}

Is this the right way to do it, or are there any pitfalls I should be aware of? For instance, are there any static initialization order problems that might occur, i.e. is inst always guaranteed to be NULL the first time getInst is called?

解决方案

Your solution is called 'double checked locking' and the way you've written it is not threadsafe.

This Meyers/Alexandrescu paper explains why - but that paper is also widely misunderstood. It started the 'double checked locking is unsafe in C++' meme - but its actual conclusion is that double checked locking in C++ can be implemented safely, it just requires the use of memory barriers in a non-obvious place.

The paper contains pseudocode demonstrating how to use memory barriers to safely implement the DLCP, so it shouldn't be difficult for you to correct your implementation.

这篇关于高效的线程安全单例在C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆