[thread] safe portable static mutex initialization
Hello, I've read Anthony Williams' articles and documentation but still have no definite answer. Thus two questions: 1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows? TIA -- The fish that is singing in Ucayali river...
Le 18/04/12 20:06, Serge Skorokhodov a écrit :
Hello,
I've read Anthony Williams' articles and documentation but still have no definite answer. Thus two questions:
1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows?
Hi, I don't see what kind of problems are your expecting. Could you clarify? What do you mean by safe? Best, Vicente
2012/4/18 Vicente J. Botet Escriba
Le 18/04/12 20:06, Serge Skorokhodov a écrit :
Hello,
I've read Anthony Williams' articles and documentation but still have no definite answer. Thus two questions:
1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows?
Hi,
I don't see what kind of problems are your expecting. Could you clarify? What do you mean by safe?
I believe Serge is asking whether a zero-initialized mutex is the same as default-constructed. It also might matter whether mutex has a non-trivial destructor. Roman Perepelitsa.
Hi,
1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows?
I don't see what kind of problems are your expecting. Could you clarify? What do you mean by safe?
Say, I need a threadsafe static factory method. It may be implemented in two ways: 1. class F { ... public: static PTR_TO_SOMETHING* create_something() { static boost::mutex m; boost::scope_lock(m); .... retrunt something_created; } }; 2. H-file: class F { private: static boost::mutex m_; ... public: static PTR_TO_SOMETHING* create_something(); }; CPP-file: boost::mutex F:m_; PTR_TO_SOMETHING* F::create_something() { boost::scope_lock(m_); .... retrunt something_created; } create_something is to be called from different threads but after main is entered. Are both of the above implementation threadsafe? TIA -- The fish that is singing in Ucayali river...
On 19/04/12 07:42, Serge Skorokhodov wrote:
Say, I need a threadsafe static factory method. It may be implemented in two ways:
1. class F { ... public: static PTR_TO_SOMETHING* create_something() { static boost::mutex m; boost::scope_lock(m); .... retrunt something_created; } };
2. H-file: class F { private: static boost::mutex m_; ... public: static PTR_TO_SOMETHING* create_something(); }; CPP-file: boost::mutex F:m_;
PTR_TO_SOMETHING* F::create_something() { boost::scope_lock(m_); .... retrunt something_created; }
create_something is to be called from different threads but after main is entered. Are both of the above implementation threadsafe?
That depends on your compiler. In case 1, the mutex is constructed when "create_something" is first called. With gcc there is a command-line option (-fthreadsafe-statics) which ensures that this is done in a thread-safe manner, so you don't have 2 threads thinking they are "first". On many builds this is enabled by default, but the user can still disable it. I don't think MSVC has thread-safe statics before VC11, but I'm not sure. I don't know about other compilers. In case 2, if you call create_something() after main() has started then it should be fine, as the class static will be fully constructed before main. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++11 thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
Hi, <skip>
That depends on your compiler. In case 1, the mutex is constructed when "create_something" is first called. With gcc there is a command-line option (-fthreadsafe-statics) which ensures that this is done in a thread-safe manner, so you don't have 2 threads thinking they are "first". On many builds this is enabled by default, but the user can still disable it. I don't think MSVC has thread-safe statics before VC11, but I'm not sure. I don't know about other compilers.
In case 2, if you call create_something() after main() has started then it should be fine, as the class static will be fully constructed before main.
Thanks alot. -- The fish that is singing in Ucayali river...
Le 19/04/12 08:42, Serge Skorokhodov a écrit :
Hi,
1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows? I don't see what kind of problems are your expecting. Could you clarify? What do you mean by safe?
Say, I need a threadsafe static factory method. It may be implemented in two ways:
1. class F { ... public: static PTR_TO_SOMETHING* create_something() { static boost::mutex m; boost::scope_lock(m); .... retrunt something_created; } };
2. H-file: class F { private: static boost::mutex m_; ... public: static PTR_TO_SOMETHING* create_something(); }; CPP-file: boost::mutex F:m_;
PTR_TO_SOMETHING* F::create_something() { boost::scope_lock(m_); .... retrunt something_created; }
create_something is to be called from different threads but after main is entered. Are both of the above implementation threadsafe?
How this is issue is related to mutex initialization? Isn't this independent from the UDT? Best, Vicente
Hi, <skip>
How this is issue is related to mutex initialization? Isn't this independent from the UDT?
Sorry, I haven't quite got your point. A static mutex variable is either thread safe in specific context (i.e. it is initialized in thread safe manner and can be used by as many threads that are interested to) or it is not (i.e. special actions required to initialize it properly, it can be used only after some explicit action etc.). I meant just that. -- The fish that is singing in Ucayali river...
It's not related to the user type, neither to mutex initialization,
it's related to variable initialization in general.
A global static variable is guaranteed to be initialized before usage.
But the initialization of static variables declared inside a function
is not guaranteed to be thread safe. So you could easily end up
calling it's constructor twice.
Saludos!
Juan
On Thu, Apr 19, 2012 at 2:48 PM, Vicente J. Botet Escriba
Le 19/04/12 08:42, Serge Skorokhodov a écrit :
Hi,
1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows?
I don't see what kind of problems are your expecting. Could you clarify? What do you mean by safe?
Say, I need a threadsafe static factory method. It may be implemented in two ways:
1. class F { ... public: static PTR_TO_SOMETHING* create_something() { static boost::mutex m; boost::scope_lock(m); .... retrunt something_created; } };
2. H-file: class F { private: static boost::mutex m_; ... public: static PTR_TO_SOMETHING* create_something(); }; CPP-file: boost::mutex F:m_;
PTR_TO_SOMETHING* F::create_something() { boost::scope_lock(m_); .... retrunt something_created; }
create_something is to be called from different threads but after main is entered. Are both of the above implementation threadsafe?
How this is issue is related to mutex initialization? Isn't this independent from the UDT?
Best, Vicente
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hello,
On Fri, Apr 20, 2012 at 8:04 AM, Juan Ramírez
It's not related to the user type, neither to mutex initialization, it's related to variable initialization in general.
A global static variable is guaranteed to be initialized before usage.
But the initialization of static variables declared inside a function is not guaranteed to be thread safe. So you could easily end up calling it's constructor twice.
That's something that boost::call_once is good at preventing. Will
Saludos! Juan
On Thu, Apr 19, 2012 at 2:48 PM, Vicente J. Botet Escriba
wrote: Le 19/04/12 08:42, Serge Skorokhodov a écrit :
Hi,
1. Is it safe to use a block level static boost::mutex on Unix and Windows? 2. Is it safe to use a file/class level static boost::mutex on Unix and Windows?
I don't see what kind of problems are your expecting. Could you clarify? What do you mean by safe?
Say, I need a threadsafe static factory method. It may be implemented in two ways:
1. class F { ... public: static PTR_TO_SOMETHING* create_something() { static boost::mutex m; boost::scope_lock(m); .... retrunt something_created; } };
2. H-file: class F { private: static boost::mutex m_; ... public: static PTR_TO_SOMETHING* create_something(); }; CPP-file: boost::mutex F:m_;
PTR_TO_SOMETHING* F::create_something() { boost::scope_lock(m_); .... retrunt something_created; }
create_something is to be called from different threads but after main is entered. Are both of the above implementation threadsafe?
How this is issue is related to mutex initialization? Isn't this independent from the UDT?
Best, Vicente
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
on Fri Apr 20 2012, Will Mason
Hello,
On Fri, Apr 20, 2012 at 8:04 AM, Juan Ramírez
wrote: It's not related to the user type, neither to mutex initialization, it's related to variable initialization in general.
A global static variable is guaranteed to be initialized before usage.
If you truly mean "static," such that it's not visible outside its translation unit, that is correct.
But the initialization of static variables declared inside a function is not guaranteed to be thread safe. So you could easily end up calling it's constructor twice.
That's something that boost::call_once is good at preventing.
Correct, for C++03. I could be mis-remembering but IIRC in C++11 function-local static variables have been given automatic threadsafe initialization. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
On 20/04/12 14:41, Dave Abrahams wrote:
on Fri Apr 20 2012, Will Mason
wrote: On Fri, Apr 20, 2012 at 8:04 AM, Juan Ramírez
wrote: But the initialization of static variables declared inside a function is not guaranteed to be thread safe. So you could easily end up calling it's constructor twice. That's something that boost::call_once is good at preventing.
Correct, for C++03. I could be mis-remembering but IIRC in C++11 function-local static variables have been given automatic threadsafe initialization.
You are right: this is guaranteed in C++11. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++11 thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
participants (7)
-
Anthony Williams
-
Dave Abrahams
-
Juan Ramírez
-
Roman Perepelitsa
-
Serge Skorokhodov
-
Vicente J. Botet Escriba
-
Will Mason