Below programs works fine. But My doubt is very beginning both threads (printEven and printOdd) is waiting for signal on conditional variable( statement pthread_cond_wait(&cond, &mutex);) then how printOdd is able to proceed further even though printEven is not able so singal at that time.
I will put it in a simple way how the number 1 is getting printed ? Can anyone please help I am literally stuck with this for long time.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t tid[2];
pthread_mutex_t mutex;
pthread_cond_t cond;
int count = 1; // Shared variable to keep track of the current number to be printed
void* printEven(void* arg) {
while (count <= 10) {
pthread_mutex_lock(&mutex);
while (count % 2 != 0) {
printf("waiting for cv signal\n");
pthread_cond_wait(&cond, &mutex);
}
printf("Even: %d\n", count++);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void* printOdd(void* arg) {
while (count <= 10) {
pthread_mutex_lock(&mutex);
while (count % 2 != 1) {
pthread_cond_wait(&cond, &mutex);
}
printf("Odd: %d\n", count++);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main() {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&tid[1], NULL, printOdd, NULL);
sleep(10);
printf("creating even thread\n ");
pthread_create(&tid[0], NULL, printEven, NULL);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
The number 1 gets printed because you are using pthread_cond_wait
in exactly the way it is meant to be used. When printOdd
is first called, count
equals 1, so count%2
equals 1, so the function does not call pthread_cond_wait.
In general, the right way to use pthread_cond_wait is,
pthread_mutex_lock(&mutex);
while (theNecessaryConditionIsNotYetMet()) {
pthread_mutex_wait(&cond, &mutex);
}
doSomethingThatRequiresTheConditionToBeMet();
pthread_mutex_unlock(&mutex);
And, the whole point of locking the mutex is that no thread should ever change whether or not the condition is met except while it has the mutex locked.