Parallel Programming Using Threads 353
atom can be divided to electrons, neutrons, and protons. Nevertheless, we still use “atomic
operation” to describe a computer operation that cannot be divided.
21.6 Thread Synchronization
The previous section described a problem in multi-threaded programs. The problem
occurs because there is no good way to predict the order in which multiple threads may
read and modify the same shared variable. There is no problem when threads do not share
data. There is no problem when they share read-only data. For the subset sum problem,
the threads share the array but it is read-only. No thread modifies the array and there is no
problem. The problem only occurs when threads are writing to, or reading from and writing
to, the same piece of memory, and the operations are interleaved in specific ways. When
we test the program, the problem will occur sometimes, and frustratingly, will not occur at
other times. This adds a significant challenge to testing threaded programs. The only way
to be sure is to use a clear mind to reason logically about how multi-thread programs work.
Threads can specify which operations must be atomic. An atomic operation is called
a critical section. Critical sections cannot interleave. In the previous example, the critical
section should include the code where the variable is read or written. If the threads takes
turns to increment and decrement the variable atomically, then the value will always remain
zero. Thus, the question becomes how to ensure that the threads take turns executing the
critical section of code. Only one thread can start a critical section at a time, and once
it starts, no other thread can enter the critical section until it finishes. The threads must
be synchronized. Synchronization restricts how threads’ operations may interleave. This is
achieved by using a mutually exclusive lock, also called mutex lock or mutex for short.
Consider an analogy of a library study room with the following rules:
• The room has a lock and only one key.
• Before a student enters the room, the student must obtain the key from the library’s
reception desk.
• Only one student can enter the room. The student must keep the key while inside the
room.
• When the student enters the room, the student must immediately lock the door.
• When the student leaves the room, the door is unlocked and the key is returned to
the library’s reception desk.
• If a student wants to use the study room but does not have the key, the student has
to wait.
A mutex comes with a pair of lock and unlock statements. The code between this pair
of statements is the critical section. A mutex lock is very similar to the lock of the library’s
study room.
• Before a thread enters the critical section, the thread must obtain the key from the
operating system.
• Only one thread can enter the critical section. The thread must lock the door and
keep the key while running the code in the critical section.
• When the thread leaves the critical section, the thread unlocks the door and returns
the key to the operating system.
• If a thread wants to enter the critical section but does not have the key, then the
thread has to wait for the key.