Files are available by executing ~classque/usp-mutex on the CS network.
This material is taken from the first 8 pages of Chapter 13 of USP
The POSIX thread library contains several synchronization constructs.
The simplest of these is the mutex lock.
A mutex, or mutex lock, is a special variable that can be either in the locked
state or the unlocked state.
If the mutex is locked, it has a distinguished thread that holds
or owns the mutex.
If the mutex is unlocked, we say that the mutex is free or
available.
The mutex also has a queue of threads that are waiting to hold the mutex.
POSIX does not require that this queue be accessed FIFO.
A mutex is meant to be held for only a short period of time.
It is usually used to protect access to a shared variable.
idea:
lock the mutex
    critical section
unlock the mutex
Unlike a semaphore, a mutex does not have a value.
Only the owner of the mutex should unlock the mutex.
Do not lock a mutex that is already locked: behavior is unspecified.
Linux has three kinds of mutexes that behave differently in this case:
The default is a fast mutex. If the owner tries to lock one
of these again, it is blocked forever.
An error checking mutex will return an error if the owner
tries to lock it again.
A recursive mutex can be locked multiple times by its owner.
The owner needs to unlock this kind a mutex once for each lock before
the mutex is available.
Note that these are for Linux only and are not portable.
Do not unlock a mutex that is not already locked.
Creating and initializing a mutex
We will only cover the simplest (and most often used) method of using
POSIX mutexes.
A mutex has type pthread_mutex_t.
Since a mutex is meant to be used by multiple threads, it is usually declared
to have static storage class.
It can be defined inside a function using the static qualifier
if it will only be used by that function
or it can be defined at the top level.
A mutex must be initialized before it is used.
This can be done when the mutex is defined, as in:
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
There are three functions that are used to manipulate a mutex:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Program 13.1 shows a counter object that can safely be used with threads.
Program 13.2 shows how to write a thread-safe version of a function that
otherwise is not safe to be used with threads.
The function yield_thread can be used to cause a thread to sleep
for a short time with a certain probability.