Re: [Boost-users] thread safety of the mutex ctor
On 18/08/2005, at 1:19 AM, boost-users-request@lists.boost.org wrote:
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? The scope of m is actually outside of your function given that it is static. Thus it will be initialised outside of your function generally before any other threads get to start up.
Cheers, -C
On 8/17/05, Christopher Hunt
On 18/08/2005, at 1:19 AM, boost-users-request@lists.boost.org wrote:
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?
The scope of m is actually outside of your function given that it is static. Thus it will be initialised outside of your function generally before any other threads get to start up.
This does not sound right to me, so I whipped up a test case... on HP-UX, given the code: #include <iostream> #include <string> class C { public: C(const std::string& str) { std::cout << "C::C(" << str << ")" << std::endl; str_ = str; } ~C() { std::cout << "C::~C(" << str_ << ")" << std::endl; } private: std::string str_; }; C c("global"); void f() { static C c("static"); } int main(int argc, char* argv[]) { C c("local"); f(); return 0; } the output will be:
g++ -o static static.cpp ./static C::C(global) C::C(local) C::C(static) C::~C(local) C::~C(static) C::~C(global)
Given my experience, this is what I expected. The static instance is not created until the function is called, and is destroyed just before global instances are destroyed. So, I would say that there is a race condition in the original code with mutex m, if there could be two threads entering my_func() for the first time. -- Matthew Peltzer -- goochrules@gmail.com
On Thu, 2005-08-18 at 06:22 +1000, Christopher Hunt wrote:
On 18/08/2005, at 1:19 AM, boost-users-request@lists.boost.org wrote:
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? The scope of m is actually outside of your function given that it is static. Thus it will be initialised outside of your function generally before any other threads get to start up.
The scope of m is in the function, not global, but it has static
duration. Unlike a global, m will only be constructed if my_func() is
ever called in your program.
That should set of warning bells in you brain.
I don't believe there are any guarantees about the thread safety of the
initialization of function scope statics. This applies not just to the
mutex class in question but any type. A particular compiler might make
this usage thread safe - or maybe only guarantee initialization of basic
types - but I don't know if it's covered by the pthread spec - and
that's not helpful anyway to boost users, in general. And of course,
the C++ standard is as usual silent on the matter.
You can make the mutex global - anonymous namespace or whatever. Since
global initializations are single threaded, you trade the threading
problem for the loss of on-demand resource usage.
Another way to deal with this kind of problem is to use a modified
singleton pattern, but to make that thread safe, you need another mutex
(unless you want to risk DCL), so seems kind of pointless for this
instance.
--
t. scott urban
participants (3)
-
Christopher Hunt
-
Matthew Peltzer
-
t. scott urban