roderick
roderick

Reputation: 91

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

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.

What I am not sure: is the following is thread-safe?

auto ptr = A::instance();

Upvotes: 0

Views: 965

Answers (1)

Matt Cummins
Matt Cummins

Reputation: 324

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.

As an aside, since the variable is static, there's no need to dynamically allocate it, you can instead do

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.

Upvotes: 1

Related Questions