7-Posix Threads - Mutex
7-Posix Threads - Mutex
These slides are based on Peter Pacheco, An Introduction to Parallel Programming Book, 2012
Critical Section
These slides are based on Peter Pacheco, An Introduction to Parallel Programming Book, 2012
Busy - Waiting
These slides are based on Peter Pacheco, An Introduction to Parallel Programming Book, 2012
Mutexes
● Since a thread that is busy-waiting may continually use the CPU, busy-waiting is generally not an
ideal solution to the problem of limiting access to a critical section.
● Two better solutions
○ Semaphores
○ Mutex
● Mutex is an abbreviation of mutual exclusion, and a mutex is a special type of variable that, together
with a couple of special functions, can be used to restrict access to a critical section to a single
thread at a time
○ A mutex can be used to guarantee that one thread “excludes” all other threads while it executes the critical
section.
Mutexes
● The Pthreads standard includes a special type for mutexes: pthread mutex t. A variable of type
pthread mutex t needs to be initialized by the system before it’s used. This can be done with a call
to
● We won’t make use of the second argument, so we’ll just pass in NULL .
Mutexes
● The call to pthread mutex lock will cause the thread to wait until no other thread is in the critical
section,
● The call to pthread mutex unlock notifies the system that the calling thread has completed
execution of the code in the critical section.
● We can use mutexes instead of busy-waiting in our global sum program by declaring a global mutex
variable,
○ The main thread initialize it, and then, instead of busy-waiting and incrementing a flag,
● The threads call pthread mutex lock before entering the critical section, and they call pthread
mutex unlock when they’re done with the critical section.
Mutexes
Mutexes
● The first thread to call pthread mutex lock will, effectively, “lock the door” to the critical section.
● Any other thread that attempts to execute the critical section code must first also call pthread mutex lock ,
○ Until the first thread calls pthread mutex unlock , all the threads that have called pthread mutex lock will block in their
calls
● After the first thread calls pthread mutex unlock , the system will choose one of the blocked threads and
allow it to execute the code in the critical section.
● This process will be repeated until all the threads have completed executing the critical section.
● Locking” and “unlocking” the door to the critical section isn’t the only metaphor that’s used in connection
with mutexes.
○ Programmers often say that the thread that has returned from a call to pthread mutex lock has “obtained the mutex”
or “obtained the lock.”
○ A thread that calls pthread mutex unlock “relinquishes” the mutex or lock.
Mutexes
● Notice that with mutexes (unlike our busy-waiting solution), the order in which the threads
execute the code in the critical section is more or less random:
● The first thread to call pthread mutex lock will be the first to execute the code in the critical
section.
● Subsequent accesses will be scheduled by the system.
○ Pthreads doesn’t guarantee (for example) that the threads will obtain the lock in the order in which they
called Pthread mutex lock .
● Only finitely many threads will try to acquire the lock. Eventually each thread will obtain the lock
Mutex Performance
● The mutex program, we see that for both versions the ratio of the run-time of the single-threaded
program with the multithreaded program is equal to the number of threads, as long as the number
of threads is no greater than the number of cores.
● In which provided thread count is less than or equal to the number of cores.
● T serial /T parallel is called the speedup,
● When the speedup is equal to the number of threads, we have achieved more or less “ideal”
performance or linear speedup.
Mutex Cost
● For example, suppose each thread generates an n × n matrix, and we want to multiply the matrices
together in thread-rank order.
Ordered thread problem - 2
● After executing the assignment in Line 10, we’d like to “notify” the thread with rank dest that it can
proceed to print the message. We’d like to do something like this:
Ordered thread problem - 2
● POSIX also provides a somewhat different means of controlling access to critical sections:
semaphores.
● Semaphores can be thought of as a special type of unsigned int , so they can take on the values 0, 1,
2, . . . .
● In most cases, we’ll only be interested in using them when they take on the values 0 and 1.
○ A semaphore that only takes on these values is called a binary semaphore.
○ 0 corresponds to a locked mutex, and 1 corresponds to an unlocked mutex.
● To use a binary semaphore as a mutex, you initialize it to 1—that is, it’s “unlocked.”
Semaphores
● Before the critical section you want to protect, you place a call to the function sem_wait.
● A thread that executes sem wait will block if the semaphore is 0. If the semaphore is nonzero, it will
decrement the semaphore and proceed.
● After executing the code in the critical section, a thread calls sem_post
● sem_post increments the semaphore, and a thread waiting in sem wait can proceed.
Semaphores
Semaphores
● Finally, note that the message-sending problem didn’t involve a critical section.
● The problem wasn’t that there was a block of code that could only be executed by one thread at a
time.
● Thread my rank couldn’t proceed until thread source had finished creating the message.
● This type of synchronization, when a thread can’t proceed until another thread has taken some
action, is sometimes called producer-consumer synchronization.
Barriers
● Barrier : Synchronizing the threads by making sure that they all are at the same point in a program.
○ Such a point of synchronization is called a barrier because no thread can proceed beyond the barrier until all
the threads have reached it
Barrier - Busy waiting and mutex
Barrier - Semaphores
Condition variables
Questions