Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling pthread_cond_signal without locking mutex

I read somewhere that we should lock the mutex before calling pthread_cond_signal and unlock the mutex after calling it:

The pthread_cond_signal() routine is used to signal (or wake up) another thread which is waiting on the condition variable. It should be called after mutex is locked, and must unlock mutex in order for pthread_cond_wait() routine to complete.

My question is: isn't it OK to call pthread_cond_signal or pthread_cond_broadcast methods without locking the mutex?

like image 331
B Faley Avatar asked Dec 28 '10 06:12

B Faley


People also ask

Does pthread_cond_signal lock mutex?

The pthread_cond_signal() routine is used to signal (or wake up) another thread which is waiting on the condition variable. It should be called after mutex is locked, and must unlock mutex in order for pthread_cond_wait() routine to complete.

What happens if you dont unlock the mutex?

If you don't, then a typical mutex is held in process memory and will simply cease to exist along with anything that might have access to it when the process terminates.

Does pthread_cond_wait lock the mutex?

The pthread_cond_wait() function blocks the calling thread, waiting for the condition specified by cond to be signaled or broadcast to. When pthread_cond_wait() is called, the calling thread must have mutex locked. The pthread_cond_wait() function atomically unlocks mutex and performs the wait for the condition.

Is pthread_cond_signal thread safe?

It is not safe to use the pthread_cond_signal() function in a signal handler that is invoked asynchronously.


1 Answers

If you do not lock the mutex in the codepath that changes the condition and signals, you can lose wakeups. Consider this pair of processes:

Process A:

pthread_mutex_lock(&mutex); while (condition == FALSE)     pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); 

Process B (incorrect):

condition = TRUE; pthread_cond_signal(&cond); 

Then consider this possible interleaving of instructions, where condition starts out as FALSE:

Process A                             Process B  pthread_mutex_lock(&mutex); while (condition == FALSE)                                        condition = TRUE;                                       pthread_cond_signal(&cond);  pthread_cond_wait(&cond, &mutex); 

The condition is now TRUE, but Process A is stuck waiting on the condition variable - it missed the wakeup signal. If we alter Process B to lock the mutex:

Process B (correct):

pthread_mutex_lock(&mutex); condition = TRUE; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); 

...then the above cannot occur; the wakeup will never be missed.

(Note that you can actually move the pthread_cond_signal() itself after the pthread_mutex_unlock(), but this can result in less optimal scheduling of threads, and you've necessarily locked the mutex already in this code path due to changing the condition itself).

like image 73
caf Avatar answered Sep 19 '22 08:09

caf