Thursday, May 29, 2014

Race conditions

A race condition in parallel programs occurs when different schedules / interleavings may cause different results.
The most typical example is the following: let two threads A and B execute (each) the program P given by

P(){
1. tmp = read(x)
2. tmp = tmp+1
3. write(x,tmp) //write in x the value of tmp
}

This code is consistent with several formal representations of parallel programs where at each statement a shared variable is accessed only once. In particular, here we consider x to be the shared variable and each thread creates a temporal local variable tmp to increment it and then write it at the original location.

Now, if  the initial value of x is 0, and the schedule is A, B (i.e. first A executes all the lines, and then B), by the end x will contain the value 2 (one increment by A, another one by B)

However, in parallel programs, one of the threads may be preempted (interrupted) the other continues running, then returns.. so there are other possible execution orders for this code.
One of them is:
A.1 (A executes the first line)
B.1
B.2
B.3
A.2
A.3

what happens here when the initial value of  x is 0?
with A.1, tmpA (tmp local to A) gets the value 0
with B.1, tmpB also gets the value 0 (it has not been changed yet)
B.2, B.3 increments and writes the new value setting x with 1 (but tmpA has not changed)
A.2 increments tmpA (it was 0, now is 1)
A.3 writes this value in x

This causes the value of x by the end of this schedule to be 1.

Thus, this code (as is) is an example of a race condition. Usually synchronization primitives are used to avoid such problems, but I'll write more about these primitives later..

No comments:

Post a Comment