Syncronizing Threads
#define P_M_L(x) pthread_mutex_lock(x)
#define P_M_U(x) pthread_mutex_unlock(x)
pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t bar_mutex = PTHREAD_MUTEX_INITIALIZER;
int foo = 0, bar = 0;
void foo_bar_inc()
{
P_M_L(&foo_mutex);
P_M_L(&bar_mutex);
bar = foo++;
P_M_U(&bar_mutex);
P_M_U(&foo_mutex);
}
void bar_foo_dec()
{
P_M_L(&bar_mutex);
P_M_L(&foo_mutex);
foo = bar--;
P_M_U(&foo_mutex);
P_M_U(&bar_mutex);
}
Here is a possible execution sequence...
Thread 1 Thread 2
foo_bar_inc();
P_M_L(&foo_mutex);
foo_bar_dec();
P_M_L(&bar_mutex)
P_M_L(&foo_mutex);
P_M_L(&bar_mutex);
Both Thread 1 and Thread 2 are waiting for mutexes to become free.
Thread 1 is waiting on foo_mutex which Thread 2 owns and Thread 2 is
waiting on bar_mutex with Thread 1 owns. This is called a DEADLOCK.
Deadlocks are your friend!
--Nawaf Bitar
/* Order of locking foo, bar ... */
void bar_foo_dec()
{
P_M_L(&bar_mutex);
while (pthread_mutex_trylock(&foo_mutex) {
P_M_U(&bar_mutex);
sleep(1);
P_M_L(&bar_mutex);
}
foo = bar--;
P_M_U(&bar_mutex);
P_M_U(&foo_mutex);
}