简体   繁体   English

如何使用 C++11 编写线程安全的 singleton

[英]How to write a thread-safe singleton using C++11

I'm not sure does this is thread-safe:我不确定这是否是线程安全的:

#include <thread>
#include <stdio.h>

class A {
public:
  static A* instance() {
      static A* ptr = new A();
      return ptr;
  }

  int val_;
};

int main(int argc, char *argv[]) {
  auto ptr = A::instance();
  printf("thread value: %d\n", ptr->val_);
  //thd1.join();
  return 0;
}

The C++ code and ARM assembly: https://godbolt.org/z/aPYarcoM9 C++ 代码和 ARM 组件: https://godbolt.org/z/aPYarcoM9

I`ve understood that the guard variable ensures the static variable initialized once only, and the guard aquire/release lock the construction of class A.我知道保护变量确保 static 变量仅初始化一次,并且保护获取/释放锁定 class A 的构造。

What I am not sure: is the following is thread-safe?我不确定:以下是线程安全的吗?

auto ptr = A::instance();

This line这条线

auto ptr = A::instance();

is thread safe because (as already mentioned) the initialization is done exactly once, and after that it always returns the same pointer and so there cannot be a race condition due to, say, another thread changing the pointer that it returns.是线程安全的,因为(如前所述)初始化只完成一次,之后它总是返回相同的指针,因此不会出现竞争条件,例如,另一个线程更改了它返回的指针。

However, using the returned pointer to modify the object it points at is definitely not thread safe, and you will require some some kind of synchronization primitive like a mutex.但是,使用返回的指针来修改它指向的 object 绝对不是线程安全的,并且您将需要某种同步原语,例如互斥锁。

As an aside, since the variable is static, there's no need to dynamically allocate it, you can instead do顺便说一句,由于变量是 static,因此无需动态分配它,您可以改为

static A* instance() {
    static A ptr;
    return &ptr;
}

I would also question if using a singleton is really what you want to be doing, as they usually lead to hard-to-maintain and hard-to-read code.我还会质疑使用 singleton 是否真的是您想要做的,因为它们通常会导致难以维护和难以阅读的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM