Whenever two processes/threads are reading and writing the same variables in a language with
SharedStateConcurrency, it is possible that one process will interfere with the other (a
RaceCondition).
For example, suppose that both processes are trying to
increment the same variable. They both have the line
x := x + 1
in them. One way for each process to execute this statement
is for it to read the variable, then add one to the value, then
write it back. Suppose the value of x was 3. If both
processes read x at the same time then they would get
the same value 3. If they then both added 1 to it then
they would both have the value 4. They would then both
write 4 back to x. The result is that both processes
incremented x, but its value is only 4, instead of 5.
For these processes to execute properly, they must ensure
that only one of them is executing the statement at a time.
A set of statements that can have only one process executing
it at a time is a
critical section. Another way of
saying this is that processes need mutually exclusive
access to the critical section.
There are several ways to implement a critical section.
If you have a single processor running all the processes
that might enter the critical section, you can DisableInterrupts
? while a
process is in the critical section.
If you have multiple processors and the critical section
doesn't take long to execute, you should use
BusyWaiting.
If the critical section is long or if you might have
interrupts during the critical section then you should
use
SemaphoresForMutualExclusion. If you are very clever
then you might be able to think up an AlternativeToCriticalSection
?.
Critical sections are very easy to spot in many
FunctionalProgrammingLanguages, because these tend to tag explicitly non-pure state changes (which are almost always critical sections).
Also see
CriticalSectionFusing.