声明为GetInstance方法的静态变量的Singleton实例,它是线程安全的吗? [英] Singleton instance declared as static variable of GetInstance method, is it thread-safe?

查看:61
本文介绍了声明为GetInstance方法的静态变量的Singleton实例,它是线程安全的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了Singleton模式的实现,其中实例变量在GetInstance方法中被声明为静态变量。像这样:

I've seen implementations of Singleton patterns where instance variable was declared as static variable in GetInstance method. Like this:

SomeBaseClass &SomeClass::GetInstance()
{
   static SomeClass instance;
   return instance;
}

我看到这种方法有以下积极方面:

I see following positive sides of this approach:


  • 代码更简单,因为只有第一次调用GetInstance时才由编译器负责创建该对象。

  • 代码更安全,因为没有其他方法可以引用实例,但是可以使用GetInstance方法,并且没有其他方法可以更改实例,但是可以在GetInstance方法内部进行。

这种方法的负面影响是什么(除了这不是非常面向对象的)?这是线程安全的吗?

What are the negative sides of this approach (except that this is not very OOP-ish) ? Is this thread-safe?

推荐答案

在C ++ 11中,它是线程安全的:

In C++11 it is thread safe:


第6.7节[stmt.dcl] p4如果在初始化变量时控件同时输入了声明,则并发执行应等待初始化完成。

§6.7 [stmt.dcl] p4 If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

在C ++ 03中:


  • 在g ++下线程安全。

    但这是因为g ++显式添加了代码来保证它。

一个问题是,如果您有两个单例,并且它们在构造和破坏期间会尝试相互使用。

One problem is that if you have two singletons and they try and use each other during construction and destruction.

请阅读以下内容:
查找C ++静态初始化顺序问题

此问题的变体是是否从全局变量的析构函数访问单例。在这种情况下,单例肯定已被破坏,但是get方法仍将返回对被破坏对象的引用。

A variation on this problem is if the singleton is accessed from the destructor of a global variable. In this situation the singleton has definitely been destroyed, but the get method will still return a reference to the destroyed object.

有很多方法可以解决,但它们很杂乱而不是值得做。只是不要从全局变量的析构函数中访问单例。

There are ways around this but they are messy and not worth doing. Just don't access a singleton from the destructor of a global variable.

更安全的定义但很丑陋:

我相信您可以添加一些适当的宏来整理一下

A Safer definition but ugly:
I am sure you can add some appropriate macros to tidy this up

SomeBaseClass &SomeClass::GetInstance()
{
#ifdef _WIN32 
Start Critical Section Here
#elif  defined(__GNUC__) && (__GNUC__ > 3)
// You are OK
#else
#error Add Critical Section for your platform
#endif

    static SomeClass instance;

#ifdef _WIN32
END Critical Section Here
#endif 

    return instance;
}

这篇关于声明为GetInstance方法的静态变量的Singleton实例,它是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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