This chapter deals with the problem of data and state corruption caused by concurrent threads. When multiple threads executing on different CPUs simultaneously modify the same data structure, that structure can be corrupted. Similarly, when a thread gets interrupted and another thread manipulates the data that the first thread was manipulating, that data can be corrupted (Baldwin, 2002).
Fortunately, FreeBSD provides a set of synchronization primitives to deal with these issues. Before I describe what synchronization primitives do, you’ll need an in-depth understanding of the abovementioned concurrency issues, also known as synchronization problems. To that end, let’s analyze a few.
Consider the following scenario in which two threads increment the same global variable. On i386, this operation might utilize the following processor instructions:
movl count,%eax # Move the value of count into a register (eax). addl $0x1,%eax # Add 1 to the value in the register. movl %eax,count # Move the value of the register into count.
Imagine that count
is currently 0
and that the first thread manages to load the current value of count
into %eax
(that is, it completes the first instruction) just before the second thread preempts it. As part of the thread switch, FreeBSD saves the value of %eax
, which is 0
, into the outgoing thread’s context. Now, suppose that the second thread manages to complete all three instructions, thereby incrementing count from 0
to 1
. If the first thread preempts the second thread, FreeBSD will restore its thread context, which includes setting %eax
to 0
. The first thread, which resumes execution at the second instruction, will now proceed to add 1
to %eax
and then store the result in count
. At this point, count equals 1
when it should equal 2
. Thus, because of a synchronization problem, we lost an update. This can also occur when the two threads are executing concurrently but just slightly out of step (that is, one thread begins executing the first instruction when the other thread begins executing the second instruction).
18.191.216.163