I am trying to understand a potential scenario and whether it is likely to be a problem.
So I have a static function that is currently thread-safe. The function being like so:
static thread_safe_func()
{
... process
}
Now in this function, I add the following:
static thread_safe_func()
{
static const Class::NonThreadSafeClassName() *array[16] = {
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
}
... code continues here
}
Now is it in itself thread-safe? The array will be initialized once for the entire duration of the application's life, so once the function thread_safe_func() has been called, and fully run, I would expect this to be thread-safe.
The issue is obviously what could occur during the first calls, what would happen in a scenario where a thread calls thread_safe_func(), the initialization of the const array occurs, but before that initialization completes, another thread is calling thread_safe_func().
Would a change to:
static ClassMutex lock = ClassMutex()
static thread_safe_func()
{
lock.Lock()
static const Class::NonThreadSafeClassName() *array[16] = {
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
Class::NonThreadSafeClassName(),
}
lock.Unlock()
... code continues here
}
be worthwhile and guarantee that this code is now thread-safe?
Static variable is a shared resource, which can be used to exchange some information among different threads. And we need to be careful while accessing such a shared resource. Hence, we need to make sure that the access to static variables in multi-threaded environment is synchronized. This is a correct statement.
Static variables are indeed shared between threads, but the changes made in one thread may not be visible to another thread immediately, making it seem like there are two copies of the variable.
Static const object would be initialized on the first entry into the function, but the initialization is not guaranteed to be thread-safe by the language.
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.
Under C++03, neither...
void foo() {
static your_variable = ...;
}
...nor...
void foo() {
lock.Lock();
static your_variable = ...;
lock.Unlock();
}
...are thread safe.
The first one is not thread safe because standard says nothing about second thread entering the function while the first thread is still performing the initialization. In fact, standard has no notion of threads at all.
The second one is not thread safe because the initialization happens when the flow of execution enters the function (for the first time), which is before lock.Lock()
.
In C++11, initialization of the local static variable is thread safe.
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