Double-Checked Lock Singleton in C++11 - c++

Is the following singleton implementation data-race free?
static std::atomic<Tp *> m_instance;
...
static Tp &
instance()
{
if (!m_instance.load(std::memory_order_relaxed))
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_instance.load(std::memory_order_acquire))
{
Tp * i = new Tp;
m_instance.store(i, std::memory_order_release);
}
}
return * m_instance.load(std::memory_order_relaxed);
}
Is the std::memory_model_acquire of the load operation superfluous? Is it possible to further relax both load and store operations by switching them to std::memory_order_relaxed? In that case, is the acquire/release semantic of std::mutex enough to guarantee its correctness, or a further std::atomic_thread_fence(std::memory_order_release) is also required to ensure that the writes to memory of the constructor happen before the relaxed store? Yet, is the use of fence equivalent to have the store with memory_order_release?
EDIT: Thanks to the answer of John, I came up with the following implementation that should be data-race free. Even though the inner load could be non-atomic at all, I decided to leave a relaxed load in that it does not affect the performance. In comparison to always have an outer load with the acquire memory order, the thread_local machinery improves the performance of accessing the instance of about an order of magnitude.
static Tp &
instance()
{
static thread_local Tp *instance;
if (!instance &&
!(instance = m_instance.load(std::memory_order_acquire)))
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!(instance = m_instance.load(std::memory_order_relaxed)))
{
instance = new Tp;
m_instance.store(instance, std::memory_order_release);
}
}
return *instance;
}

I think this a great question and John Calsbeek has the correct answer.
However, just to be clear a lazy singleton is best implemented using the classic Meyers singleton. It has garanteed correct semantics in C++11.
§ 6.7.4
... If control enters
the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for
completion of the initialization. ...
The Meyer's singleton is preferred in that the compiler can aggressively optimize the concurrent code. The compiler would be more restricted if it had to preserve the semantics of a std::mutex. Furthermore, the Meyer's singleton is 2 lines and virtually impossible to get wrong.
Here is a classic example of a Meyer's singleton. Simple, elegant, and broken in c++03. But simple, elegant, and powerful in c++11.
class Foo
{
public:
static Foo& instance( void )
{
static Foo s_instance;
return s_instance;
}
};

That implementation is not race-free. The atomic store of the singleton, while it uses release semantics, will only synchronize with the matching acquire operation—that is, the load operation that is already guarded by the mutex.
It's possible that the outer relaxed load would read a non-null pointer before the locking thread finished initializing the singleton.
The acquire that is guarded by the lock, on the other hand, is redundant. It will synchronize with any store with release semantics on another thread, but at that point (thanks to the mutex) the only thread that can possibly store is the current thread. That load doesn't even need to be atomic—no stores can happen from another thread.
See Anthony Williams' series on C++0x multithreading.

See also call_once.
Where you'd previously use a singleton to do something, but not actually use the returned object for anything, call_once may be the better solution.
For a regular singleton you could do call_once to set a (global?) variable and then return that variable...
Simplified for brevity:
template< class Function, class... Args>
void call_once( std::once_flag& flag, Function&& f, Args&& args...);
Exactly one execution of exactly one of the functions, passed as f to the invocations in the group (same flag object), is performed.
No invocation in the group returns before the abovementioned execution of the selected function is completed successfully

Related

std::call_once vs std::mutex for thread-safe initialization

I'm a bit confused about the purpose of std::call_once. To be clear, I understand exactly what std::call_once does, and how to use it. It's usually used to atomically initialize some state, and make sure that only one thread initializes the state. I've also seen online many attempts to create a thread-safe singleton with std::call_once.
As demonstrated here, suppose you write a thread safe singleton, as such:
CSingleton& CSingleton::GetInstance()
{
std::call_once(m_onceFlag, [] {
m_instance.reset(new CSingleton);
});
return *m_instance.get();
}
Okay, I get the idea. But I thought that the only thing std::call_once really guarantees is that the passed function will only be executed once. But does it also guarantee that if there is a race to call the function between multiple threads, and one thread wins, the other threads will block until the winning thread returns from the call?
Because if so, I see no difference between call_once and a plain synchronization mutex, like:
CSingleton& CSingleton::GetInstance()
{
std::unique_lock<std::mutex> lock(m_mutex);
if (!m_instance)
{
m_instance.reset(new CSingleton);
}
lock.unlock();
return *m_instance;
}
So, if std::call_once indeed forces other threads to block, then what benefits does std::call_once offer over a regular mutex? Thinking about it some more, std::call_once would certainly have to force the other threads to block, or whatever computation was accomplished in the user-provided function wouldn't be synchronized. So again, what does std::call_once offer above an ordinary mutex?
One thing that call_once does for you is handle exceptions. That is, if the first thread into it throws an exception inside of the functor (and propagates it out), call_once will not consider the call_once satisfied. A subsequent invocation is allowed to enter the functor again in an effort to complete it without an exception.
In your example, the exceptional case is also handled properly. However it is easy to imagine a more complicated functor where the exceptional case would not be properly handled.
All this being said, I note that call_once is redundant with function-local-statics. E.g.:
CSingleton& CSingleton::GetInstance()
{
static std::unique_ptr<CSingleton> m_instance(new CSingleton);
return *m_instance;
}
Or more simply:
CSingleton& CSingleton::GetInstance()
{
static CSingleton m_instance;
return m_instance;
}
The above is equivalent to your example with call_once, and imho, simpler. Oh, except the order of destruction is very subtly different between this and your example. In both cases m_instance is destroyed in reverse order of construction. But the order of construction is different. In your m_instance is constructed relative to other objects with file-local scope in the same translation unit. Using function-local-statics, m_instance is constructed the first time GetInstance is executed.
That difference may or may not be important to your application. Generally I prefer the function-local-static solution as it is "lazy". I.e. if the application never calls GetInstance() then m_instance is never constructed. And there is no period during application launch when a lot of statics are trying to be constructed at once. You pay for the construction only when actually used.
Slight variation on standard C++ solution is to use lambda inside the usual one:
// header.h
namespace dbj_once {
struct singleton final {};
inline singleton & instance()
{
static singleton single_instance = []() -> singleton {
// this is called only once
// do some more complex initialization
// here
return {};
}();
return single_instance;
};
} // dbj_once
Please observe
anonymous namespace implies default static linkage for variables inside. Thus do not put this inside it. This is header code.
worth repeating: this is safe in presence of multiple threads (MT) and is supported as a such by all major compilers
inside is a lambda which is guaranteed to be called only once
this pattern is also safe to use in header only situations
If you read this you'll see that std::call_once makes no guarantee about data-races, it's simply a utility function for performing an action once (which will work across threads). You shouldn't presume that is has anything close to the affect of a mutex.
as an example:
#include <thread>
#include <mutex>
static std::once_flag flag;
void f(){
operation_that_takes_time();
std::call_once(flag, [](){std::cout << "f() was called\n";});
}
void g(){
operation_that_takes_time();
std::call_once(flag, [](){std::cout << "g() was called\n";});
}
int main(int argc, char *argv[]){
std::thread t1(f);
std::thread t2(g);
t1.join();
t2.join();
}
could print both f() was called and g() was called. This is because in the body of std::call_once it will check whether flag was set then set it if not then call the appropriate function. But while it is checking or before it set flag another thread may call call_once with the same flag and run a function at the same time. You should still protect calls to call_once with a mutex if you know another thread may have a data race.
EDIT
I found a link to the proposal for the std::call_once function and thread library which states that concurrency is guaranteed to only call the function once, so it should work like a mutex (y)
More specifically:
If multiple calls to call_once with the same flag are executing concurrently in separate threads, then only one thread shall call func, and no thread shall proceed until the call to func has completed.
So to answer your question: yes, other threads will be blocked until the calling thread returns from the specified functor.

Double-checked locking in C++11? [duplicate]

This question already has answers here:
Double-Checked Lock Singleton in C++11
(3 answers)
Closed 9 years ago.
Here is a Java example problem from http://www.ibm.com/developerworks/java/library/j-dcl/index.html
public static Singleton getInstance()
{
if (instance == null) //#4
{
synchronized(Singleton.class) { //#1
if (instance == null) //#2
instance = new Singleton(); //#3
}
}
return instance;
}
It seems this isn't safe because #3 can set instance to not null before the constructor is executed thus when another thread checks instance on #4 it will not be null and return a instance that hasn't been constructed properly.
Apparently using a function variable wont help because it may be optimized out or just be executed in a way that also sets the value to instance when we don't want it to.
I was thinking wouldn't the easiest way is to have a function new Singleton(); so it is completed before assigning it to instance. Now the issue is how do I tell C++ a function should NOT be inline? I think Singleton* make_singleton() volatile should do that but i'm positive I am wrong.
I'll ignore the singleton bits for a while and assume you need this for lazy initialization and not for silly things like singletons.
I suggest forgetting about double-checked locking. C++ provides a very useful tool for this kind of situation in the form of std::call_once, so use that.
template <typename T>
struct lazy {
public:
// needs constraining to prevent from doing copies
// see: http://flamingdangerzone.com/cxx11/2012/06/05/is_related.html
template <typename Fun>
explicit lazy(Fun&& fun) : fun(std::forward<Fun>(fun)) {}
T& get() const {
std::call_once(flag, [this] { ptr.reset(fun()); });
return *ptr;
}
// more stuff like op* and op->, implemented in terms of get()
private:
std::once_flag flag;
std::unique_ptr<T> ptr;
std::function<T*()> fun;
};
// --- usage ---
lazy<foo> x([] { return new foo; });
This is exactly the type of situation atomics are designed for. By storing the result into an atomic, you know that the compiler can't sequence any critical stores or operations after the atomic is set. Atomics are both for emitting processor instruction primitives to ensure the necessary sequential consistency (e.g., for cache coherency across cores) and for telling the compiler which semantics must be preserved (and therefore to limit the types of reorderings it can do). If you use an atomic here, it won't matter if the function is inlined because whatever inlining the compiler does will have to preserve the semantics of the atomic itself.
You may also be interested in looking into std::call_once which is also designed for this situation, and more specifically for the situation where multiple threads may need something done, but exactly one of them should do it.

C++11: Safe double checked locking for lazy initialization. Possible?

I have read many questions considering thread-safe double checked locking (for singletons or lazy init). In some threads, the answer is that the pattern is entirely broken, others suggest a solution.
So my question is: Is there a way to write a fully thread-safe double checked locking pattern in C++? If so, how does it look like.
We can assume C++11, if that makes things easier. As far as I know, C++11 improved the memory model which could yield the needed improvements.
I do know that it is possible in Java by making the double-check guarded variable volatile. Since C++11 borrowed large parts of the memory model from the one of Java, so I think it could be possible, but how?
Simply use a static local variable for lazily initialized Singletons, like so:
MySingleton* GetInstance() {
static MySingleton instance;
return &instance;
}
The (C++11) standard already guarantees that static variables are initialized in a threadsafe manner and it seems likely that the implementation of this at least as robust and performant as anything you'd write yourself.
The threadsafety of the initialization can be found in §6.7.4 of the (C++11) standard:
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
Since you wanted to see a valid DCLP C++11 implementation, here is one.
The behavior is fully thread-safe and identical to GetInstance() in Grizzly's answer.
std::mutex mtx;
std::atomic<MySingleton *> instance_p{nullptr};
MySingleton* GetInstance()
{
auto *p = instance_p.load(std::memory_order_acquire);
if (!p)
{
std::lock_guard<std::mutex> lck{mtx};
p = instance_p.load(std::memory_order_relaxed);
if (!p)
{
p = new MySingleton;
instance_p.store(p, std::memory_order_release);
}
}
return p;
}

Is this a valid alternative to the double checked locking?

I would like to use singleton pattern in a multithreaded program. Double-checked locking method seems suitable for its efficiency, however this method is broken and not easy to get right.
I write the following code hoping that it works as an alternative to the double-checked locking. Is it a correct implementation of a thread-safe singleton pattern?
static bool created = false;
static Instance *instance = 0;
Instance *GetInstance() {
if (!created) {
Lock lock; // acquire a lock, parameters are omitted for simplicity
if (!instance) {
instance = new Instance;
} else {
created = true;
}
}
return instance;
}
The first call will create Instance. The second call will set created to true. And finally, all other calls will return a well initialized instance.
http://voofie.com/content/192/alternative-to-double-checked-locking-and-the-singleton-pattern/
No, this doesn't help. If the writes to created and instance are non-atomic then there is no guarantee that the values are visible to a thread that doesn't lock the mutex.
e.g. Thread 1 calls getInstance. created is false, and instance is null, so it locks the mutex and creates a new instance. Thread 1 calls getInstance again, and this time sets created to true. Thread 2 now calls getInstance. By the vagaries of the processor's memory management it sees created as true, but there is no guarantee that it also sees instance as non-null, and even if it does there is no guarantee that the memory values for the pointed-to instance are consistent.
If you're not using atomics then you need to use mutexes, and must use them for all accesses to a protected variable.
Additional info: If you are using mutexes, then the compiler and runtime work together to ensure that when one thread releases a mutex lock and another thread acquires a lock on that same mutex then the second thread can see all the writes done by the first. This is not true for non-atomic accesses, and may or may not be true for atomic accesses, depending on what memory ordering constraints the compiler and runtime guarantee for you (with C++11 atomics you can choose the ordering constraints).
It has the same reliability of the double-checked locking.
You can get more with "triple check", or even "quadruple-check", but full reliability can be demonstrated to be impossible.
Please note that declaring a local-static variable will make the compiler to implement itself your same logic.
#include<memory>
#include "Instance.h" //or whatever...
Instance* GetInstance()
{
static std::unique_ptr<Instance> p(new Instance);
return p.get();
}
If the compiler is configured for multithreading environment, it sould protect the static p with a mutex and manage the lock when initializing p at the very first call. It also should chain p destruction to the tail of the "at_exit" chain, so that -at program end- proper destruction will be performed.
[EDIT]
Since this is a requirement for C++11 and is implemented only in some C++03 pre-standard, check the compiler implementation and settings.
Right now, I can only ensure MinGW 4.6 on and VS2010 already did it.
No. There's absolutely no difference between your code and double
checked locking. The correct implementation is:
static std::mutex m;
Singleton&
Singleton::instance()
{
static Singleton* theOneAndOnly;
std::lock_guard l(m);
if (theOneAndOnly == NULL)
theOneAndOnly = new Singleton;
return *theOneAndOnly;
}
It's hard to imagine a case where this would cause a problem, and it is
guaranteed. You do aquire the lock each time, but aquiring an
uncontested mutex should be fairly cheap, you're not accessing
Singleton's that much, and if you do end up having to access it in the
middle of a tight loop, there's nothing to stop you from acquiring a
reference to it before entering the loop, and using it.
This code contains a race-condition, in that created can be read while it is concurrently being written to by a different thread.
As a result, it has undefined behaviour, and is not a valid way of writing that code.
As KennyTM pointed out in the comments, a far better alternative is:
Instance* GetInstance() { static Instance instance; return &instance; }
your solution will work fine, but it does one more check.
the right double check locking looks like,
static Instance *instance = 0;
Instance *GetInstance() {
if (instance == NULL) //first check.
{
Lock lock; //scope lock.
if (instance == NULL) //second check, the second check must under the lock.
instance = new Instance;
}
return instance;
}
the double check locking will have a good performance for it does not acquire the lock every time. and it is thread-safe the locking will gurentee there is only one instance created.

Any comments to this (hopefully) 100% safe double-check-locking replacement for singletons

As Scott Meyers and Andrei Alexandrescu outlined in this article the simple try to implement the double-check locking implementation is unsafe in C++ specifically and in general on multi-processor systems without using memory barriers.
I was thinking a little bit about that and came to a solution that avoids using memory barriers and should also work 100% safe in C++. The trick is to store a copy of the pointer to the instance thread-local so each thread has to acquire the lock for the first times it access the singleton.
Here is a little sample code (syntax not checked; I used pthread but all other threading libs could be used):
class Foo
{
private:
Helper *helper;
pthread_key_t localHelper;
pthread_mutex_t mutex;
public:
Foo()
: helper(NULL)
{
pthread_key_create(&localHelper, NULL);
pthread_mutex_init(&mutex);
}
~Foo()
{
pthread_key_delete(&localHelper);
pthread_mutex_destroy(&mutex);
}
Helper *getHelper()
{
Helper *res = pthread_getspecific(localHelper);
if (res == NULL)
{
pthread_mutex_lock(&mutex);
if (helper == NULL)
{
helper = new Helper();
}
res = helper;
pthread_mutex_unlock(&mutex);
pthread_setspecific(localHelper, res);
}
return res;
}
};
What are your comments/opinions?
Do you find any flaws in the idea or the implementation?
EDIT:
Helper is the type of the singleton object (I know the name is not the bet...I took it from the Java examples in the Wikipedia article about DCLP).
Foo is the Singleton container.
EDIT 2:
Because it seems to be a little bit misunderstanding that Foo is not a static class and how it is used, here an example of the usage:
static Foo foo;
.
.
.
foo.getHelper()->doSomething();
.
.
.
The reason that Foo's members are not static is simply that I was able to create/destroy the mutex and the TLS in the constructor/destructor.
If a RAII version of a C++ mutex / TLS class is used Foo can easily be switched to be static.
You seem to be calling:
pthread_mutex_init(&mutex);
...in the Helper() constructor. But that constructor is itself called in the function getHelper() (which should be static, I think) which uses the mutex. So the mutex appears to be initialised twice or not at all.
I find the code very confusing, I must say. Double-checked locking is not that complex. Why don't you start again, and this time create a Mutex class, which does the initialisation, and uses RAI to release the underlying pthread mutex? Then use this Mutex class to implement your locking.
This isn't the double-checked locking pattern. Most of the potential thread safety issues of the pattern are due to the fact the the a common state is read outside of a mutually exclusive lock, and then re-checked inside it.
What you are doing is checking a thread local data item, and then checking the common state inside a lock. This is more like a standard single check singleton pattern with a thread local cached value optimization.
To a casual glance it does look safe, though.
Looks interesting! Clever use of thread-local storage to reduce contention.
But I wonder if this is really different from the problematic approach outlined by Meyers/Alexandrescu...?
Say you have two threads for which the singleton is uninitialized (e.g. thread local slot is empty) and they run getHelper in parallel.
Won't they get into the same race over the helper member? You're still calling operator new and you're still assigning that to a member, so the risk of rogue reordering is still there, right?
EDIT: Ah, I see now. The lock is taken around the NULL-check, so it should be safe. The thread-local replaces the "first" NULL-check of the DCLP.
Obviously a few people are misunderstanding your intent/solution. Something to think about.
I think the real question to be asked is this:
Is calling pthread_getspecific() cheaper than a memory barrier?
Are you trying to make a thread-safe singleton or, implement Meyers & Andrescu's tips? The most straightforward thing is to use a
pthread_once
as is done below. Obviously you're not going for lock-free speed or anything, creating & destroying mutexes as you are so, the code may as well be simple and clear - this is the kind of thing pthread_once was made for. Note, the Helper ptr is static, otherwise it'd be harder to guarantee that there's only one Helper object:
// Foo.h
#include <pthread.h>
class Helper {};
class Foo
{
private:
static Helper* s_pTheHelper;
static ::pthread_once_t once_control;
private:
static void createHelper() { s_pTheHelper = new Helper(); }
public:
Foo()
{ // stuff
}
~Foo()
{ // stuff
}
static Helper* getInstance()
{
::pthread_once(&once_control, Foo::createHelper);
return s_pTheHelper;
}
};
// Foo.cpp
// ..
Helper* Foo::s_pTheHelper = NULL;
::pthread_once_t Foo::once_control = PTHREAD_ONCE_INIT;
// ..