OK. The example here is provided using pthread lib in c.
In textbook I came across the following code:
//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
This code works out pretty fine. I just wonder will the following code also works?
//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);//signal the conditional variable but the lock is not held
What's the pros and cons for the following code?
PS. Suppose the cooperating thread has the code:
//for thread 1
pthread_mutex_lock(&lock);
while(!should_wake_up)
pthread_cond_wait(&cond, &lock);
pthead_mutex_unlock(&lock);
PS2. I came across some other question, which points out that if we don't want signal being lost, we must use lock to make sure that the associated predicate (in this case, is should_wake_up) can not be changed when the lock is held in thread 1. In this case, this seems not to be the issue. Link to the post: [1]: signal on condition variable without holding lock. I think his issue is that he forget about locking. But my question is different.
For normal usage, you can unlock the mutex before signalling a condition variable.
The mutex protects the shared state (in this case the should_wake_up flag). Provided the mutex is locked when modifying the shared state, and when checking the shared state, pthread_cond_signal can be called without the mutex locked and everything will work as expected.
Under most circumstances, I would recommend calling pthread_cond_signal after calling pthread_mutex_unlock as a slight performance improvement. If you call pthread_cond_signal before pthread_mutex_unlock then the waiting thread can be woken by the signal before the mutex is unlocked, so the waiting thread then has to go back to sleep, as it blocks on the mutex that is still held by the signalling thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With