Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading. Do I need critical sections for read-only access?

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?

like image 770
ManuelSchneid3r Avatar asked Nov 14 '12 20:11

ManuelSchneid3r


People also ask

What is critical section in multithreading?

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.

Why do we need critical 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.

Do you need mutex for reading?

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.

What will happen if multiple threads accessing the same resource?

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.


2 Answers

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.

like image 76
Sergey Kalinichenko Avatar answered Nov 06 '22 06:11

Sergey Kalinichenko


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.

like image 45
PiotrNycz Avatar answered Nov 06 '22 06:11

PiotrNycz