I have a bunch of threads. They should access a singleton containing configuration data which is initialized once when the singleton is created. Hence on the first access. So further actions on the singleton are just read-only. Do I need critical sections in this case?
A critical section is a section of code that needs to be executed without outside interference - i.e. without another thread potentially affecting/being affected by "intermediate" states within the section.
Typically, critical sections prevent thread and process migration between processors and the preemption of processes and threads by interrupts and other processes and threads. Critical sections often allow nesting. Nesting allows multiple critical sections to be entered and exited at little cost.
Yes. If thread a reads a variable while thread b is writing to it, you can read an undefined value. The read and write operation are not atomic, especially on a multi-processor system.
Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.
It appears that because the data is created lazily on first access, the pointer or the reference to your singleton is read-write. This means that you do need a critical section.
In fact, the desire to avoid a critical section while keeping the lazy initialization in this situation has been so universally strong that it lead to the creation of the double-checked locking antipattern.
On the other hand, if you were to initialize your singleton eagerly before the reads, you would be able to avoid a critical section for accessing an immutable object through a constant pointer / reference.
I understand your question as there is lazy initialization in your singleton. It is initialized only for the first read.
The next consecutive reads are thread safe. But what about concurrent read during initialization?
If you have situation like this:
SomeConfig& SomeConfig::getInstance()
{
static SomeConfig instance;
return instance;
}
Then it depends on your compiler. According to this post in C++03 it was implementation dependent if this static initialization is thread safe.
For C++11 it is thread safe - see answers to this post, citation:
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.
It is worth to note that read only access to global variables 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