Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;:这是我的singleton threadsafe的getInstance()方法吗?_C++_Boost_Singleton_Thread Safety - Fatal编程技术网

C++ c++;:这是我的singleton threadsafe的getInstance()方法吗?

C++ c++;:这是我的singleton threadsafe的getInstance()方法吗?,c++,boost,singleton,thread-safety,C++,Boost,Singleton,Thread Safety,我目前正在尝试使用boost::mutex编写线程安全的单例(至少在构造和销毁方面)。我听说boost互斥不能静态初始化(很抱歉,我丢失了我读到它的链接),所以为了解决这个问题,我尝试了以下方法,如果threadsafety for construction and Destroyment是: static T& getInstance() { #ifndef STATIC_VARIABLES_ARE_THREADSAFE

我目前正在尝试使用boost::mutex编写线程安全的单例(至少在构造和销毁方面)。我听说boost互斥不能静态初始化(很抱歉,我丢失了我读到它的链接),所以为了解决这个问题,我尝试了以下方法,如果threadsafety for construction and Destroyment是:

                static T& getInstance()
            {
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
                boost::mutex mutex; 
                boost::lock_guard lock(mutex);
#endif
                static T instance;
                return instance;
            }
这是线程安全的,还是应该使用boost::call_一次?boost once是否比这种方法有任何性能优势

编辑: 好吧,我的第一个想法显然不正确。澄清问题。boost::mutex可以安全地静态初始化吗?像这样:

class Singleton
{
private:
static boost::mutex m_mutex;

public:
static Singleton & getInstance()
{
    boost::lock_guard lock(m_mutex);
    static T instance;
    return instance;
}

};
这是一种有效的方法,还是静态初始化boost::mutex实际上不安全(我就是这么读的)

EDIT2
啊,顺便说一句,那是链接

因为函数的每个条目都会创建自己的锁,锁将完全无用;任何数量的线程都可以进入函数,锁定不同的锁,同时开始处理静态数据

您可以在文件(或类静态)范围内创建锁;这将确保及时创建它,前提是您不在
main()
之前启动线程。但是,即使在初始化静态数据之后,这也会序列化函数的条目


为什么不首先在文件(或类静态)范围内定义静态数据?

您确实需要使用锁定。但是,您建议的
boost::mutex
方案被破坏了,因为您在堆栈上分配了互斥体,多个并发调用方将各自获得自己的互斥体。

GCC提供了静态变量的线程安全初始化。
因此,如果您使用GCC,您不需要关心静态变量的正确初始化

尝试使用Meyers单例实现

class MySingleton {
public:
  static MySingleton& getInstance() {
    static MySingleton instance;
    return instance;
  }
private:
  MySingleton();
  ~MySingleton();
  MySingleton(const MySingleton&)= delete;
  MySingleton& operator=(const MySingleton&)= delete;

};

MySingleton::MySingleton()= default;
MySingleton::~MySingleton()= default;


// Usage
int main() {
  MySingleton::getInstance();
}

既然你这么说了,那就很明显了,谢谢!我想我得走boost/std::call_once路线了。boost互斥体不能静态初始化是真的吗?那么,我可以安全地静态初始化boost互斥体吗?如前所述,我在某个地方读到,情况并非如此,因此我不确定这是否是一种有效的方法。见更新后的帖子!将其初始化为函数范围静态变量是不安全的;这是因为进入函数的两个线程可能同时尝试初始化互斥锁本身。作为类级静态,只要在静态初始化完成之前不访问它,它是安全的(这是任何静态非POD类型的问题-请参阅)@bdonlan:注意,尽管这对于C++03是正确的,在C++中,静态本地保证线程安全的运行时初始化。这是一个选项。你检查了这个问题:C++中的线程安全的单线程()是有效的,但是我的问题是如果可以将静态互斥体静态初始化,因为如果是这样的话,这个问题很容易解决。单身是邪恶的,除非你真的。。。真的必须:)