Guaranteeing atomic operations through semaphores and mutual exclusions
Let’s try to zoom in on a shared resource and see what happens in the CPU. We will provide a simple and effective way to explain where exactly the data races start from. They were already thoroughly discussed in Chapter 6. Everything we learn here should be considered as an addition, in a sense, but the analysis methodology of concurrent and parallel processing remains the same as earlier. But now, we focus on concrete low-level problems.
Let’s look closely at the following snippet:
int shrd_res = 0; //Some shared resource. void thread_func(){ Â Â Â Â shrd_res ++; Â Â Â Â std::cout << shrd_res; }
It is a very simple piece of code in which a variable is incremented and printed out. According to C++ standards, such a modification is an undefined behavior in multithreaded environments. Let’s see how – instead of going through the process’...