This question already has answers here:
Is Meyers' implementation of the Singleton pattern thread safe?
(6 answers)
Closed 5 years ago.
I know this is an often asked question, but as there are so many variants, I'd like to re-state it, and hopefully have an answer reflecting the current state. Something like
Logger& g_logger() {
static Logger lg;
return lg;
}
Is the constructor of variable lg guaranteed to run only once?
I know from previous answers that in C++03, this is not; in C++0x draft, this is enforced. But I'd like a clearer answer to
In C++11 standard (not draft), is the thread-safe initialization behavior finalized?
If the above is yes, in current latest releases of popular compilers, namely gcc 4.7, vc 2011 and clang 3.0, are they properly implemented?
The relevant section 6.7:
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 control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
Then there's a footnote:
The implementation must not introduce any deadlock around execution of the initializer.
So yes, you're safe.
(This says nothing of course about the subsequent access to the variable through the reference.)
--fno-threadsafe-statics also worth mentioning. In gcc:
Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.
Also, have a look at the old thread Are function static variables thread-safe in GCC?
Related
Related to Is a static boost::wregex instance thread-safe? but for the standarized version. Can I call regex_search from several threads with the same regex object?
Claiming that std::regex is thread-safe in every respect is a pretty bold statement. The C++11 standard does not make such guarantees for the regex library.
However, looking at the prototype of std::regex_search shows that it it takes the basic_regex object as a const argument. This means that it is protected by the standard library's guarantee that the const modifier implies thread-safety of the function with respect to that argument.
In standardese, that is:
[17.6.5.9/1]
This section specifies requirements that implementations shall meet to prevent data races (1.10). Every standard library function shall meet each requirement unless otherwise specified. Implementations may prevent data races in cases other than those specified below.
[17.6.5.9/3]
A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const arguments, including this.
So, barring a bug in the implementation of the standard library that you use, it appears that calls to std::regex_search are thread-safe with respect to the regex object that is passed in.
Other thoughts:
Just because std::regex_search is re-entrant with respect to its regex argument does not mean that you are completely out of the water. Performing an operation that modifies a regex in a non-thread-safe manner at the same time as a thread-safe call such as std::regex_search is still undefined behaviour. basic_regex's assignment operator, std::swap, and basic_regex::imbue come to mind as non-thread-safe functions with respect to the basic_regex they operate on. Knowing this, it might be better for you to make a copy of the regex object, which should come at a minimal performance cost, for each thread to use/modify at its leisure.
While Sean's answer is true of the standard, individual implementation may fall short. VC++ 2013, at least, looks like it has race conditions in its copy constructor and in a lazily evaluated variable.
C++03 Standard [basic.start.init] point 3 states:
It is implementation-defined whether or not the dynamic
initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace
scope is done before the first statement of main. If the
initialization is deferred to some point in time after the first
statement of main, it shall occur before the first use of any
function or object defined in the same translation unit as the
object to be initialized.
Microsoft Compilers, according to Additional Startup Considerations, perform the initialization prior to main().
I have been unable to obtain documentation stating the behaviour for GNU and Sun Forte compilers.
Can anyone:
Point me in the direction of documentation that describes the behaviour of the GNU and Forte compilers with respect to dynamic initialization (I have checked the GCC manual and found nothing relating to dynamic initialization).
Comment on the thread-safety of deferred dynamic initialization (if two threads attempt to invoke a function from the same translation unit that contains a non-local object).
FWIW, I observed the behaviour of GNU's g++ and SUN's CC and both performed the initalization prior to main though I don't accept this as a definitive answer. (I can post the very simple code I used to observe if anyone is interested but I felt the question is long enough)
The definitive answer is that all compilers do static initialization
before main, unless the objects are in a DLL which is loaded later.
In practice, it's (almost) impossible to meet the requirements in the
text you cite otherwise. (Think of what happens if there is a cycle.)
I heard that after some version of gcc using simply something like:
static A* a = new A();
return a;
Is thread-safe for a singleton and one wouldn't need something adapted from say http://locklessinc.com/articles/singleton_pattern/ anymore...
Does anyone have a specific reference or link to where I can read about this?
Section 6.7 of draft standard (n3337.pdf), point 4:
The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage
duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a
block-scope entity with static storage duration, if applicable, is performed before its block is first entered.
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.88 If control re-enters the declaration recursively while the variable is being
initialized, the behavior is undefined.
GCC follows the cross-vendor Itanium C++ ABI. The relevant sections covering thread-safe initialization of function-local statics are 2.8 Initialization guard variables and 3.3.2 One-time Construction API, which says:
An implementation that does not anticipate supporting multi-threading may simply check the first byte (i.e., the byte with lowest address) of that guard variable, initializing if and only if its value is zero, and then setting it to a non-zero value.
However, an implementation intending to support automatically thread-safe, one-time initialization (as opposed to requiring explicit user control for thread safety) may make use of the following API functions:
...
There were some bugs in the early GCC implementation of that API, I think they are all fixed and it works correctly from GCC version 4.3 (possibly earlier, I don't recall and can't find a reference right now.)
However, Singleton is a bad, bad pattern, do not use it!
This question already has answers here:
Is Meyers' implementation of the Singleton pattern thread safe?
(6 answers)
Closed 5 years ago.
I know this is an often asked question, but as there are so many variants, I'd like to re-state it, and hopefully have an answer reflecting the current state. Something like
Logger& g_logger() {
static Logger lg;
return lg;
}
Is the constructor of variable lg guaranteed to run only once?
I know from previous answers that in C++03, this is not; in C++0x draft, this is enforced. But I'd like a clearer answer to
In C++11 standard (not draft), is the thread-safe initialization behavior finalized?
If the above is yes, in current latest releases of popular compilers, namely gcc 4.7, vc 2011 and clang 3.0, are they properly implemented?
The relevant section 6.7:
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 control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
Then there's a footnote:
The implementation must not introduce any deadlock around execution of the initializer.
So yes, you're safe.
(This says nothing of course about the subsequent access to the variable through the reference.)
--fno-threadsafe-statics also worth mentioning. In gcc:
Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.
Also, have a look at the old thread Are function static variables thread-safe in GCC?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is static init thread-safe with VC2010?
I know that gcc and llvm-clang emit code to initialise local static variables in a threadsafe manner (which allows one to escape the static order initialisation fiasco by wrapping global statics in functions).
This msdn blog post, however, is the best documentation I can find of vcc's behaviour in these circumstances, and purports that static initialisation cannot ever be threadsafe, because the initialiser for a local static could recursively call into the same scope.
I don't buy this argument - it is clearly a programming error if the initialiser relies on its own result.
So, given that this article is from 2004, that gcc and clang can do it, and that the current msvc documentation is ambiguous (stating that 'assigning' to a local static isn't threadsafe, but nothing more):
Is the initialisation of local statics now threadsafe in MSVC?
If not, why not, since it is clearly possible for gcc to do this, but very difficult for the programmer to add in afterwards.
The C++0x Standard says:
§6.7 Declaration statement [stmt.dcl]
4/ The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered.
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.88
If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
[ Example:
int foo(int i) {
static int s = foo(2*i); // recursive call - undefined
return i+1;
}
—end example ]
88) The implementation must not introduce any deadlock around execution of the initializer.
As expected, it is quite complete.
However the fact is that even older versions of gcc already complied with this, and in fact do even better: in case of recursive initialization, an exception is thrown.
Finally, regarding a programmer adding it afterward: you can normally do it if you have something like Compare And Swap available, and use a sufficiently small variable, relying on zero-initialization of the variable to mark its non-computed state. However I do agree it's much easier if it's baked in.
I am afraid I stopped followed VC++ progresses though, so I don't know where it stands now. My only advice would be... look it up at assembly level.
I heard it is already implemented in vs2010, but can not find any reference. Anyway in c++0x standard such initializations are explicitly required to be thread-safe, so sooner or later ms would comply I guess.