Boost logo

Boost Users :

Subject: Re: [Boost-users] What is the best idiom for using call_once ?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-11-17 07:51:48


Le 17/11/12 10:54, John M. Dlugosz a écrit :
> Consider the issue of a static variable inside a function: the idea
> is to initialize on first use (if any). But we all know this is not
> thread safe, at least for the first call.
>
> Since the C++11 standard library includes a feature just like
> boost::call_once, that would seem to be the proper way to address this
> moving forward. And, I don't see anything in the standard that would
> be more powerful and direct for this purpose, which leaves me to
> wonder if there is still more that should have been done.
>
> But, my question is, what is the "best" or slickest way to use it (for
> this purpose)? If Lambda functions are available (which is not the
> case on every platform my code needs to support) _and_ the type of
> variable in question has some kind of "dead" state available, it's not
> too bad to write something like this:
>
> VarType obtain_singleton()
> {
> static boost::once_flag f=BOOST_ONCE_INIT;
> static VarType retval;
> boost::call_once (f, [] { retval=the_real_initialization(); });
> return retval;
> }
>
> //...later
> // static VarType val= the_real_initialization; // !!not thread
> safe on first call!!
> static VarType val= obtain_singleton(); // do this instead (and
> write it in another function for conciseness)
>
Hi,

your code suffers from the problem you try to avoid "But we all know
this is not thread safe, at least for the first call" at least in c++98
as you are using static variables.
> However, it's more awkward if I can't declare VarType retval to be
> pre-initialized to some "dead" value, or if it has any constructor at
> all and would itself re-introduce the thread safety issue! In short,
> it only works correctly (without the availability of the constexpr
> feature and types having constructors of such a nature) for primitive
> types.
>
> I've worked around it using a pointer and having the real_init
> function itself contain a static variable. That makes me think that
> there should be a simpler way to do it. Or, once the "best way" has
> been determined, why can't it be done once and succinctly reused?
>
> Anyone have one to share?
>
here they are some pointers that while not responding exactly to your
question them could help you.

http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-6-double-checked-locking.html

http://stackoverflow.com/questions/12302057/c11-safe-double-checked-locking-for-lazy-initialization-possible

Best,
Vicente


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net