For example, the node::node()
constructor in the following snippet accesses the globals node::count
and ::tail
without any multithread guards. Does the C++ standard guarantee that the output would always be a permutation of 0 1 2
(regardless of the order)?
#include <stdio.h>
struct node *tail;
struct node
{
static int count;
int index;
node *prev;
node()
{ index = count++; prev = tail; tail = this; }
};
int node::count;
node one, two[2];
int main(int argc, char *argv[])
{
for(node *p = tail; p; p = p->prev)
printf("%d\n", p->index);
return 0;
}
I am looking for an answer based on the (applicable) standard, not for implementation or compiler specific behaviors. There are a number of related questions on SO but it's not entirely clear how they directly apply to this particular and rather basic case (Is C++ static member variable initialization thread-safe?, Is local static variable initialization thread-safe in C++11? etc).
Thread Safety Static variables are not thread safe. Instance variables do not require thread synchronization unless shared among threads. But, static variables are always shared by all the threads in the process. Hence, access to static variable is not thread safe.
Yes, Java static initializers are thread safe (use your first option). However, if you want to ensure that the code is executed exactly once you need to make sure that the class is only loaded by a single class-loader. Static initialization is performed once per class-loader.
According to following resources, in C++(Specially Visual C++) scoped static variable initialization isn't thread safe.
Global variables are generally written before main() function. In line 4, a and b are declared as two global variables of type int . The variable a will be automatically initialized to 0. You can use variables a and b inside any function.
Initialization of global variables is guaranteed single-threaded as long as the program doesn't itself start a thread (e.g. in a constructor of some global variable); once that happens, the implementation is then allowed to parallellize remaining initializations, to some extent.
[basic.start.init]/2 ...Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. If a program starts a thread (30.3), the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit. If a program starts a thread, the subsequent unordered initialization of a variable is unsequenced with respect to every other dynamic initialization. Otherwise, the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamic initialization. [ Note: This definition permits initialization of a sequence of ordered variables concurrently with another sequence. —end note ]
"Indeterminately sequenced" is the part that guarantees single-threaded execution. By definition, the notion of sequenced {before, after, indeterminately} is only meaningful within a single thread:
[intro.execution]/13 Sequenced before is a ... relation between evaluations executed by a single thread...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With