Synchronize two threads to print ordered even and odd numbers in C

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 );
	}
}

  7 comments for “Synchronize two threads to print ordered even and odd numbers in C

  1. Durga
    December 27, 2013 at 2:53 PM

    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 ?

    Like

    • Suresh Gorijavolu
      March 26, 2014 at 6:02 PM

      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.

      Like

      • sreedhar
        April 24, 2016 at 7:37 PM

        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.

        Like

  2. viren
    May 10, 2014 at 9:17 AM

    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)

    Like

  3. Neethan
    February 24, 2016 at 10:24 AM

    pthread_cond_wait( &condition_var, &count_mutex ); //Waits for signal from another thread

    pthread_cond_signal( &condition_var ); //send a signal to another thread

    Like

  4. Amit Rai
    September 7, 2017 at 7:24 PM

    it prints one more than required value. need to put the print statement before increment of the count variable.

    Like

  5. December 29, 2017 at 12:15 PM

    JAI SHRI RAM !!!
    Is it possible to write the program by not using the MUTEX?
    Please let me know.

    Like

Leave a Reply to ravikiran sattigeri (@ravikiran_ssp) Cancel reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: