Documente Academic
Documente Profesional
Documente Cultură
1 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
www2.chrishardick.com
PTHREADS: MUTEXES
the basic pthread synchronization mechanism
mutex stands for mutual exclusion.
the job of a mutex is to guarantee mutual exclusive access to a
given resource (or set of resources)
the most common method to synchronize common resources
(global data, file descriptors, etc.) among threads is to ensure
that only one thread is allowed to interact with the shared
resource @ a given time. I.e. access to the shared resource is
mutually exclusive (mutex)
the most basic (& most common) usage is to create one mutex
for each shared resource and to surround all access to the
shared resouce w/ mutex_lock() & mutex_unlock() calls
3/3/2016 12:50 AM
PTHREADS: MUTEXES
2 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
3/3/2016 12:50 AM
PTHREADS: MUTEXES
3 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
// in
pthread_mutexattr_t*
p_MutexAttr);
default attributes
mutexes which are dynamically initialized need to be destroyed
using pthread_mutex_destroy()
you can safely destroy a mutex which has no thread(s) blocked
on it & is unlocked
how do you know if no threads are blocked on the mutex & that
it is unlocked? You have to have a solid grasp of the program
3/3/2016 12:50 AM
PTHREADS: MUTEXES
4 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
logic!!!
/*
* destroy a dynamically initialized mutex
*
* RETURN
* ======
* 0 = success
* else - see discussion on pthreads and errors
*/
int pthread_mutex_destroy (pthread_mutex_t*
p_Mutex)
// in
/*
* an example
*/
#include <pthread.h>
#include <string.h>
// for strerror_r()
char szEMsg[80];
pthread_mutex_t* p_DynamicMutex =
(pthread_mutex_t*) malloc
(sizeof(pthread_mutex_t));
int iRC = pthread_mutex_init (p_DynamicMutex,
NULL);
if (iRC != 0)
{
3/3/2016 12:50 AM
PTHREADS: MUTEXES
5 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
strerror_r(iRC, szEMsg,
sizeof(szEMsg));
cout << "ERR: UNABLE TO INIT DYNAMIC
MUTEX: " << szEMsg << endl;
return false;
}
...
iRC = pthread_mutex_destroy (p_DynamicMutex);
if (iRC != 0)
{
strerror_r(iRC, szEMsg,
sizeof(szEMsg));
cout << "ERR: UNABLE TO DESTROY
DYNAMIC MUTEX: " << szEMsg << endl;
return false;
}
3/3/2016 12:50 AM
PTHREADS: MUTEXES
6 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
// in
3/3/2016 12:50 AM
PTHREADS: MUTEXES
7 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
*
* RETURN
* ======
* 0 = success
* else - see discussion on pthreads and errors
*/
int pthread_mutex_unlock (pthread_mutex_t*
p_Mutex);
// in
// in
A simple example
/*
* All accesses and modifications to x should
3/3/2016 12:50 AM
PTHREADS: MUTEXES
8 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
be bracketed by calls to
* pthread_mutex_lock() and
pthread_mutex_unlock() as follows:
*/
pthread_mutex_lock(&Mutex);
/*
* operate on x
*/
pthread_mutex_unlock(&Mutex);
4. MUTEX SIZE
How much code should be within a mutex (i.e. how much
data--and other shared resources--should be protected by a
single mutex)?
When converting existing non thread-safe code (e.g. an existing
C library or (even worse) an existing fortran library), it's easiest
to lock before entering and unlock after returning. This is known
a a BIG MUTEX and depending on your situation, it might be
your best (or only) solution
As a general rule, resources which are usually used together
should use the same mutex. Unrelated resources should use
separate mutexes
5. AVOIDING DEADLOCKS
3/3/2016 12:50 AM
PTHREADS: MUTEXES
9 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
Anytime your code need to hold more than one mutex @ a time,
you have to be careful to avoid deadlock
The classic deadlock
Thread 1
Thread 2
========
========
lock mutex_a
lock mutex_b
|
lock mutex_b
lock mutex_a
- blocked forever waiting for mutex_b
3/3/2016 12:50 AM
PTHREADS: MUTEXES
10 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
lock mutex_b
lock mutex_a (blocked)
|
perform processing
3/3/2016 12:50 AM
PTHREADS: MUTEXES
11 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
unlock mutex_a
unlock mutex_b
wake up (obtained mutex_a)
|
lock mutex_b
...
perform processing
|
unlock mutex_a
unlock mutex_b
|
...
B. SPIN LOCK
Lock the first mutex normally (blocking), but for any additional
mutexes - use non-blocking mutexes (pthread_mutex_trylock())
If any lock fails, unlock in reverse order and try again
Unlocking the mutexes in the reverse order reduces the
spinning for other threads
Thread 1
Thread 2
========
========
3/3/2016 12:50 AM
PTHREADS: MUTEXES
12 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
lock mutex_a
try-lock mutex_b
lock mutex_a (blocked)
|
perform processing
unlock mutex_b
unlock mutex_a
|
wake up (obtained mutex_a)
...
try-lock mutex_b
|
perform processing
|
unlock mutex_b
unlock mutex_a
C. CHAINING
Useful for traversing linked lists and other tree data structures
A type of locking hierarchy
Lock #1, Lock #2, Unlock #1, Lock #3, Unlock #2
Thread 1
========
3/3/2016 12:50 AM
PTHREADS: MUTEXES
13 of 13
about:reader?url=http://www2.chrishardick.com/Notes/Computing/C/pth...
3/3/2016 12:50 AM