understanding of pthread_cond_wait() and pthread_cond_signal() understanding of pthread_cond_wait() and pthread_cond_signal() multithreading multithreading

understanding of pthread_cond_wait() and pthread_cond_signal()


pthread_cond_signal does not unlock the mutex (it can't as it has no reference to the mutex, so how could it know what to unlock?) In fact, the signal need not have any connection to the mutex; the signalling thread does not need to hold the mutex, though for most algorithms based on condition variables it will.

pthread_cond_wait unlocks the mutex just before it sleeps (as you note), but then it reaquires the mutex (which may require waiting) when it is signalled, before it wakes up. So if the signalling thread holds the mutex (the usual case), the waiting thread will not proceed until the signalling thread also unlocks the mutex.

The common use of condition vars is something like:

thread 1:    pthread_mutex_lock(&mutex);    while (!condition)        pthread_cond_wait(&cond, &mutex);    /* do something that requires holding the mutex and condition is true */    pthread_mutex_unlock(&mutex);thread2:    pthread_mutex_lock(&mutex);    /* do something that might make condition true */    pthread_cond_signal(&cond);    pthread_mutex_unlock(&mutex);

The two threads have some shared data structure that the mutex is protecting access to. The first thread wants to wait until some condition is true then immediately do some operation (with no race condition opportunity for some other thread to come in between the condition check and action and make the condition false.) The second thread is doing something that might make the condition true, so it needs to wake up anyone that might be waiting for it.


Here is a typical example: thread 1 is waiting for a condition, which may be fulfilled by thread 2.

We use one mutex and one condition.

pthread_mutex_t mutex;pthread_cond_t condition;

thread 1 :

pthread_mutex_lock(&mutex); //mutex lockwhile(!condition){    pthread_cond_wait(&condition, &mutex); //wait for the condition}/* do what you want */pthread_mutex_unlock(&mutex);

thread 2:

pthread_mutex_lock(&mutex);/* do something that may fulfill the condition */pthread_mutex_unlock(&mutex);pthread_cond_signal(&condition); //wake up thread 1

Edit

As you can see in the pthread_cond_wait manual:

It atomically releases mutex and causes the calling thread to block on the condition variable cond; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable".


I have taken example from herehttps://www.geeksforgeeks.org/condition-wait-signal-multi-threading/

and modified to this,

#include <pthread.h> #include <stdio.h> #include <unistd.h> // Declaration of thread condition variable pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // declaring mutex pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // Thread function void releaseFun() {     // Let's signal condition variable cond    printf("Signaling condition variable cond\n");     pthread_cond_signal(&cond); }// Thread function void* blockedThread() {    // acquire a lock     pthread_mutex_lock(&lock);     printf("Waiting on condition variable cond\n");    pthread_cond_wait(&cond, &lock);     // release lock     pthread_mutex_unlock(&lock);     printf("Returning thread\n");     return NULL; }    // Driver code int main() {     pthread_t tid;    // Create thread 1     pthread_create(&tid, NULL, blockedThread, NULL);     // sleep for 1 sec so that thread 1     // would get a chance to run first     sleep(1);     releaseFun();    // wait for the completion of thread 2     pthread_join(tid, NULL);     return 0; }

Output: gcc test_thread.c -lpthread

Waiting on condition variable cond

Signaling condition variable cond

Returning thread

Locking and unlocking of the thread will happen only when blockThread's pthread_cond_wait() function is signaled to be unblocked.