Problem
You have two threads, that independently print even and odd values. The goal is to synchronize these threads so as to get a non-decreasing ordered set of numbers and order should preserve natural ordering of numbers. So the output should be 1,2,3,4,5,6,7,8…..
It is an interesting problem and could be solved with a conditional variable.
Solution
Following is C implementation of the solution:
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1(void*);
void *functionCount2(void*);
int count = 0;
#define COUNT_DONE 200
int main()
{
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, functionCount1, NULL);
pthread_create(&thread2, NULL, functionCount2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
// Print odd numbers
void *functionCount1(void*)
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 2 != 0 ) {
pthread_cond_wait( &condition_var, &count_mutex );
}
count++;
printf("Counter value functionCount1: %d\n",count);
pthread_cond_signal( &condition_var );
if ( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
// print even numbers
void *functionCount2(void*)
{
for(;;) {
// Lock mutex and then wait for signal to release mutex
pthread_mutex_lock( &count_mutex );
if ( count % 2 == 0 ) {
pthread_cond_wait( &condition_var, &count_mutex );
}
count++;
printf("Counter value functionCount2: %d\n",count);
pthread_cond_signal( &condition_var );
if( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
Hi,
Why do we need the wait/condition here ? I implemented this, and just used a mutex (around a global variable). That works too.
Am I missing something ?
LikeLike
if you do not use condition variable you will waste machine cycles by way of spinning.
means you will potentially several times lock / unlock mutexes before you actually do your work.
LikeLike
Also without wait and signal you may not get the output exactly odd and even from each thread. It could be like 1 thread prints the 1,2,3,4,5 and other thread prints 6,7 etc, as the same thread can acquire the lock again number of times, as the OS may give more CPU time slice for 1 thread alone.
LikeLike
if ( count % 2 != 0 ) {
pthread_cond_wait( &condition_var, &count_mutex );
}
above code should really re-validate the predicate before blindly believing that predicate has become true…i would really replace that if with while (in both threads)
LikeLike
pthread_cond_wait( &condition_var, &count_mutex ); //Waits for signal from another thread
pthread_cond_signal( &condition_var ); //send a signal to another thread
LikeLike
it prints one more than required value. need to put the print statement before increment of the count variable.
LikeLike
JAI SHRI RAM !!!
Is it possible to write the program by not using the MUTEX?
Please let me know.
LikeLike