In the context of parallel or concurrent programs, you will often hear the term race condition. This describes a problem when two pieces of code try to modify the same variable (or other location in memory).
Race conditions can be notoriously difficult to find, reproduce and debug.
To start with we have a variable a that is set to 7. I’ll show you what can happen, step-by-step, when two pieces of code try to use and modify that variable.
Both a = a + 35 and a = a – 10 will execute “at the same time”. I have “at the same time” in scare quotes because we don’t really know what “at the same time” means. Computers process instructions sequentially, this means that one operation has to come before the other. Let’s see how that can play out…
From looking at the code in the beginning, you may have guessed that the value of a after these operations would be 42, and that was indeed the intent. However, because of the race condition the value of a ended up being -3. Not at all what we wanted!
Probably the most common way to handle race conditions is to use locks. Here’s how the above process would look using locks…
Locks prevent race conditions by making sure that only one piece of code can access a memory location at any time. Locks can become very complicated to manage and are themselves the source of many bugs. Consider what would happen if some piece of code did not unlock the memory it was modifying! Or worse, did not lock it in the first place, in which case we fall back to the race condition.
Locks are not the only way to handle race conditions (though they are the most common). Another way to handle race conditions is to use immutable variables. This means that no code is allowed to change the value of a. Immutable variables will be the subject of another WITH article, so I won’t explain them here.