Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help understanding this text extracted from B.Stroustrup's new book

In section 41.2.1 Memory Location of his new book, B.Stroustrup writes the following:

Consider two global variables b and c:

// thread1
char c = 0;
void f()
{
   c = 1;
   int x = c;
} 

// thread2
char b = 0;
void g()
{
   b = 1;
   int y = b;
}

Now, x==1 and y==1, as anyone would expect. Why is this even worth saying? Consider what might happen if a linker allocated c and b in the same word in memory and (like most modern hardware) the machine could not load or store anything smaller than a word:

enter image description here

Without a well-defined and reasonable memory model, thread 1 might read the word containing b and c, change c, and write the word back into memory. At the same time thread 2 could do the same with b. Then, whichever thread managed to read the word first and wichever thread managed to write its result back into memory last would determine the result. We might get 10, 01, or 11 (but not 00). The memory model saves us from such chaos; we get 11. The reason that 00 cannot happen is that the initialization of b and c are done (by the compiler or the linker) before either thread starts.

Assuming that the phrase:

We might get 10, 01, or 11 (but not 00)

refers to the final values of the variables x and y respectively, how could we get 10 and 01 without a sensible memory model. I just can't see how this would be possible.

I also couldn't understand what the author meant to say when he wrote the last sentence above:

The reason that 00 cannot happen is that the initialization of b and c are done (by the compiler or the linker) before either thread starts.

like image 954
Wake up Brazil Avatar asked Feb 12 '14 22:02

Wake up Brazil


1 Answers

The reason that you could get 01 or 10 without a sensible memory model is because thread operations occur concurrently and the read and write of the memory are not atomic. They require two steps - step 1: read, step 2: write. Without a sensible memory model, the following would be possible:

Thread 1: Reads 00 Memory:00

Thread 2: Reads 00 Memory:00

Thread 1: Writes 10 Memory:10

Thread 2: Writes 01 Memory:01

Result: 01

The problem of multiple threads accessing the same resource is common with multi-threaded programming. For example, multiple threads that need access to the same static member variable. The way that we protect against threads trampling over each other is with mutexes and critical sections. However, in the case that is presented we don't need to do that because the memory model handles it for us (is sensible).

The reason that 00 is not possible: the memory is initialised to 00 before either thread starts, so neither thread tramples over what the other thread has done and sets the memory to 00.

like image 145
acarlon Avatar answered Oct 12 '22 09:10

acarlon