thread safety of the mutex ctor
I hope this isn't a stupid question, but.... Is the boost mutex constructor thread-safe? I am writing a singleton template and trying to avoid the static initialisation/destruction order fiasco. I envisage two threads accessing a function like this concurrently: template<typename T> boost::shared_ptr<T> my_func() { static boost::mutex m; boost::mutex::scoped_lock l(m); static boost::shared_ptr<T> p(new T); return p; } and my worry is that both threads could attempt to do the static initialisation of m concurrently. Is there protection against this? Is it even possible to protect against this? I've tried to use boost::call_once, which would give sufficient guarantees but it's quite inflexible as nothing can be passed to or from the function being called. I know that integral types (like a pthread_t) of static storage are initialised before main() and before constructors of statically allocated objects are called, which means there would be no problem using a pthread_t above. However, constructors of objects of static storage are called at a time when there could be multiple threads running. Am I worrying about nothing? Or is there a problem here? Thanks, James -- James E Taylor ___________________________________ NOCC, http://nocc.sourceforge.net
FYI Matthew Wilson gave a technique (in "Imperfect C++") for handling this,
by turning the mutex initialization into an integer initialization (that
doesn't have a problem with [multiple] simultaneous threads entering the
function)
It uses STLSoft's spin_mutex, and looks pretty much like what you have
already:
<code>
#include
I hope this isn't a stupid question, but....
Is the boost mutex constructor thread-safe?
I am writing a singleton template and trying to avoid the static initialisation/destruction order fiasco.
I envisage two threads accessing a function like this concurrently:
template<typename T> boost::shared_ptr<T> my_func() { static boost::mutex m; boost::mutex::scoped_lock l(m);
static boost::shared_ptr<T> p(new T); return p; }
and my worry is that both threads could attempt to do the static initialisation of m concurrently. Is there protection against this? Is it even possible to protect against this?
I've tried to use boost::call_once, which would give sufficient guarantees but it's quite inflexible as nothing can be passed to or from the function being called.
I know that integral types (like a pthread_t) of static storage are initialised before main() and before constructors of statically allocated objects are called, which means there would be no problem using a pthread_t above. However, constructors of objects of static storage are called at a time when there could be multiple threads running.
Am I worrying about nothing? Or is there a problem here?
Thanks, James
-- James E Taylor
James E Taylor wrote:
I hope this isn't a stupid question, but....
Is the boost mutex constructor thread-safe?
Clearly it's unsafe for multiple threads to call a constructor on the same block of memory concurrently. To answer the real question, dynamic initialisation of local static variables is generally not thread-safe.
and my worry is that both threads could attempt to do the static initialisation of m concurrently. Is there protection against this? Is it even possible to protect against this?
I've tried to use boost::call_once, which would give sufficient guarantees but it's quite inflexible as nothing can be passed to or from the function being called.
I don't see that there's any other way to do this using current C++ and Boost. Ben.
participants (3)
-
Ben Hutchings
-
James E Taylor
-
Pablo Aguilar