c++:我的单例的 getInstance() 方法是线程安全的吗?

发布于 2024-11-09 15:46:03 字数 1043 浏览 3 评论 0原文

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

                static T& getInstance()
            {
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
                boost::mutex mutex; 
                boost::lock_guard lock(mutex);
#endif
                static T instance;
                return instance;
            }

是线程安全的,还是应该使用 boost: :调用一次?与这种方法相比,提升一次会给我带来任何性能优势吗?

编辑: 好吧,我的第一个想法显然是不正确的。为了澄清问题。 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 不安全(这是我读到的)?

编辑2: 啊,顺便说一下,这是链接 http:// uint32t.blogspot.com/2007/12/you-lazy-bastard-part-1.html

I am currently trying to write a threadsafe singleton (at least in terms of construction and destruction) using boost::mutex. I read that boost mutex can't be initialized statically(I lost the link where I read it, sorry) so to work around that I tried this, if threadsafety for construction and destruction is:

                static T& getInstance()
            {
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
                boost::mutex mutex; 
                boost::lock_guard lock(mutex);
#endif
                static T instance;
                return instance;
            }

is that threadsafe, or should I use boost::call_once? Will boost once give me any performance benefit over this approach?

EDIT:
Okay, my first idea was obviously not correct. To clearify the question. Can a boost::mutex safely be initialized statically? Like this:

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

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

};

Is that a working approach or is it in fact not safe to init boost::mutex statically (which is what I read)?

EDIT2:
Ah, that was the link by the way http://uint32t.blogspot.com/2007/12/you-lazy-bastard-part-1.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

护你周全 2024-11-16 15:46:03

由于函数的每个入口都会创建自己的锁,因此锁将完全无用;任意数量的线程都可以进入该函数,锁定不同的锁,并同时开始处理静态数据。

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

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

Since each entry to the function will create its own lock, the lock will be completely useless; any number of threads can enter the function, lock different locks, and start messing with the static data at the same time.

You could create the lock at file (or class static) scope; this would ensure it's created in time, provided that you don't start threads before main(). However, this would also serialize entry to the function even after the static data is initialized.

Why not just define your static data at file (or class static) scope in the first place?

最单纯的乌龟 2024-11-16 15:46:03

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

GCC provides thread safe initialization of static variables.
So, if you use GCC you do not need to care about proper initialization of static variables

GRAY°灰色天空 2024-11-16 15:46:03

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

You do need to use locking. However, the boost::mutex scheme you propose is broken since you allocate the mutex on the stack and multiple concurrent callers would each get their own mutex.

内心激荡 2024-11-16 15:46:03

尝试使用 Meyers Singleton 实现。

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();
}

更多信息...

Try to use the Meyers Singleton implementation.

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();
}

More info...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文