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

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.

Related

Is the execution of a c++ 11 atomic object also atomic ?

I have a object and all its function should be executed in sequential order.
I know it is possible to do that with a mutex like
#include <mutex>
class myClass {
private:
std::mutex mtx;
public:
void exampleMethod();
};
void myClass::exampleMethod() {
std::unique_lock<std::mutex> lck (mtx); // lock mutex until end of scope
// do some stuff
}
but with this technique a deadlock occurs after calling an other mutex locked method within exampleMethod.
so i'm searching for a better resolution.
the default std::atomic access is sequentially consistent, so its not possible to read an write to this object at the same time, but now when i access my object and call a method, is the whole function call also atomic or more something like
object* obj = atomicObj.load(); // read atomic
obj.doSomething(); // call method from non atomic object;
if yes is there a better way than locking the most functions with a mutex ?
Stop and think about when you actually need to lock a mutex. If you have some helper function that is called within many other functions, it probably shouldn't try to lock the mutex, because the caller already will have.
If in some contexts it is not called by another member function, and so does need to take a lock, provide a wrapper function that actually does that. It is not uncommon to have 2 versions of member functions, a public foo() and a private fooNoLock(), where:
public:
void foo() {
std::lock_guard<std::mutex> l(mtx);
fooNoLock();
}
private:
void fooNoLock() {
// do stuff that operates on some shared resource...
}
In my experience, recursive mutexes are a code smell that indicate the author hasn't really got their head around the way the functions are used - not always wrong, but when I see one I get suspicious.
As for atomic operations, they can really only be applied for small arithmetic operations, say incrementing an integer, or swapping 2 pointers. These operations are not automatically atomic, but when you use atomic operations, these are the sorts of things they can be used for. You certainly can't have any reasonable expectations about 2 separate operations on a single atomic object. Anything could happen in between the operations.
You could use a std::recursive_mutex instead. This will allow a thread that already owns to mutex to reacquire it without blocking. However, if another thread tries to acquire the lock it will block.
As #BoBTFish properly indicated, it is better to separate your class's public interface, which member functions acquire non-recursive lock and then call private methods which don't. Your code must then assume a lock is always held when a private method is run.
To be safe on this, you may add a reference to std::unique_lock<std::mutex> to each of the method that requires the lock to be held.
Thus, even if you happen to call one private method from another, you would need to make sure a mutex is locked before execution:
class myClass
{
std::mutex mtx;
//
void i_exampleMethod(std::unique_lock<std::mutex> &)
{
// execute method
}
public:
void exampleMethod()
{
std::unique_lock<std::mutex> lock(mtx);
i_exampleMethod(lock);
}
};

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.

Writing a C++ class that can be used as static, but needs a lock

I need to write class that loads shared libraries. The dlopen() / dlerror() sequence needs a lock to be thread safe.
class LibLoader {
public:
LibLoader(string whichLib);
bool Load() { Wait(lock); ... dlopen() ... dlerror() ... }
bool Unload() { Wait(lock); ... dlclose() ... dlerror() ... }
bool IsLoaded() {...}
// ... access to symbols...
private:
static Lock lock;
}
Lock Lock::lock;
The users of this class (there will be multiple at the same time) will want to make it a static member of this class to avoid loading a shared library multiple time for every object of the class:
class NeedsALib {
public:
NeedsALib() { if (!myLib.IsLoaded()) { myLib.Load(); } }
private:
static LibLoader myLib;
}
LibLoader::myLib;
The problem with this code is that it may / will crash, because it relies on the order of statics being destructed when the program terminates. If the lock is gone before myLib it will crash....
How can this be written in a safe manner that is thread safe and doesn't rely on the order of static destruction ?
Unfortunately, I think the only way to avoid this is to both use unportable one-time initialization directives, and to avoid destroying the lock at all. There are two basic problems you need to deal with:
What happens if two threads race to access the lock for the first time? [ie, you cannot lazy-create the lock]
What happens if the lock is destroyed too early? [ie, you cannot statically-create the lock]
The combination of these constraints forces you to use a non-portable mechanism to create the lock.
On pthreads, the most straightforward way to handle this is with the PTHREAD_MUTEX_INITIALIZER, which lets you statically initialize locks:
class LibLoader{
static pthread_mutex_t mutex;
// ...
};
// never destroyed
pthread_mutex_t LibLoader::mutex = PTHREAD_MUTEX_INITIALIZER;
On windows, you can use synchronous one-time initialization.
Alternately, if you can guarentee that there will only be one thread before main runs, you can use the singleton pattern without destruction, and just force the lock to be touched before main():
class LibLoader {
class init_helper {
init_helper() { LibLoader::getLock(); }
};
static init_helper _ih;
static Lock *_theLock;
static Lock *getLock() {
if (!_theLock)
_theLock = new Lock();
return _theLock;
}
// ...
};
static init_helper LibLoader::_ih;
static Lock *LibLoader::_theLock;
Note that this makes the possibly non-portable (but highly likely to be true) assumption that static objects of POD type are not destroyed until all non-POD static objects have been destroyed. I'm not aware of any platform in which this is not the case.
Wrapping up the requirements: multiple LibLoader instances are needed, each for a different library, but a single lock must exist to ensure they don't overwrite each others' error codes.
One way would be to rely on static initialization and destruction order within a file.
Better way would be not to make LibLoader static field in NeedsALib (and the like). It seems these client classes can be passed an instance of the right LibLoader in the constructor.
If creating LibLoader instances outside of its client classes isn't convenient, you can make all static fields (the lock and the loaders) pointers and use singleton pattern with lazy initialization. Then as you create the first loader, it ends up creating the lock as well. Singleton itself would require locking here, but you could perhaps run it before spawning your threads. Destruction would also be explicit and under your control. You can also do this with loaders only (retaining static lock).
Also, if LibLoader doesn't have a lot of state to store, you can make each client class (NeedsALib etc) instantiate its own LibLoader. This is admittedly quite wasteful, though.

Double-Checked Lock Singleton in C++11

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

How do I make sure there is only 1 mutex?

I am running some thread safe code here. I am using a mutex to protect the section of code that needs to be run only by only 1 thread at a time. The problem I have is using this code sometimes I end up with 2 Mutex objects. This is a static function by the way. How do I make sure only 1 mutex object gets created??
/*static*/ MyClass::GetResource()
{
if (m_mutex == 0)
{
// make a new mutex object
m_mutex = new MyMutex();
}
m_mutex->Lock();
Simply create m_mutex outside of GetResource(), before it can ever be called - this removes the critical section around the actual creation of the mutex.
MyClass::Init()
{
m_mutex = new Mutex;
}
MyClass::GetResource()
{
m_mutex->Lock();
...
m_mutex->Unlock();
}
The issue is the thread could be interrupted after checking if m_mutex is 0, but not before it creates the mutex, allowing another thread to run through the same code.
Don't assign to m_mutex right away. Create a new mutex, and then do an atomic compare exchange.
You don't mention your target platform, but on Windows:
MyClass::GetResource()
{
if (m_mutex == 0)
{
// make a new mutex object
MyMutex* mutex = new MyMutex();
// Only set if mutex is still NULL.
if (InterlockedCompareExchangePointer(&m_mutex, mutex, 0) != 0)
{
// someone else beat us to it.
delete mutex;
}
}
m_mutex->Lock();
Otherwise, replace with whatever compare/swap function your platform provides.
Another option is to use one-time initialization support, which is available on Windows Vista and up, or just pre-create the mutex if you can.
Lazy mutex initialization isn't really appropriate for static methods; you need some guarantee that nobody races to the initialization. The following uses the compiler to generate a single static mutex for the class.
/* Header (.hxx) */
class MyClass
{
...
private:
static mutable MyMutex m_mutex; // Declares, "this mutex exists, somewhere."
};
/* Compilation Unit (.cxx) */
MyMutex MyClass::m_mutex; // The aforementioned, "somewhere."
MyClass::GetResource()
{
m_mutex.Lock();
...
m_mutex.Unlock();
}
Some other solutions will require extra assumptions of your fellow programmers. With the "call init()" method, for instance, you have to be sure that the initialization method were called, and everybody would have to know this rule.
Why use a pointer anyway? Why not replace the pointer with an actual instance that does not require dynamic memory management? This avoids the race condition, and does not impose a performance hit on every call into the function.
Since it is only to protect one specific section of code, simply declare it static inside the function.
static MyClass::GetResource()
{
static MyMutex mutex;
mutex.Lock();
// ...
mutex.Unlock();
The variable is a local variable with static storage duration. It is explicitly stated in the Standard:
An implementation is permitted to perform early initialization of other block-scope variables with static or
thread storage duration under the same conditions that an implementation is permitted to statically initialize
a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is
initialized the first time control passes through its declaration; such a variable is considered initialized upon
the completion of its initialization. If the initialization exits by throwing an exception, the initialization
is not complete, so it will be tried again the next time control enters the declaration. If control enters
the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for
completion of the initialization.
The last sentence is of particular interest to you.