CITS2002 Systems Programming  
prev
next CITS2002 CITS2002 schedule  

A condition variable example

Let's consider a typical 'producer/consumer' example, in which the producer() thread create items and makes them available, and the consumer() thread uses them.

This is a very typical problem requiring synchronization as we don't wish either thread to block indefinitely waiting for the other, and the consumer should only execute when it's known that there's at least one new item available:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>

#define MAX_ITEMS     10

pthread_cond_t cond_recv    = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_send    = PTHREAD_COND_INITIALIZER;

pthread_mutex_t cond_mutex  = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;

bool full=false;
int  count=0;

void *producer(void *thread_id)
{
    while(true) {
	pthread_mutex_lock(&cond_mutex);
        while(full) {
            pthread_cond_wait(&cond_recv, &cond_mutex) ;
        }

        pthread_mutex_unlock(&cond_mutex);
        pthread_mutex_lock(&count_mutex);

        ++count;
        full = true;
        printf("producer(%li):%i\n", pthread_self() , count);

        pthread_cond_broadcast(&cond_send);
        pthread_mutex_unlock(&count_mutex);

        if((count >= MAX_ITEMS) {
            break;
        }
    }
}
















void *consumer(void *thread_id)
{
    while(true) {
        pthread_mutex_lock(&cond_mutex);

        while(!full) {
            pthread_cond_wait(&cond_send , &cond_mutex) ;
        }

        pthread_mutex_unlock(&cond_mutex);
        pthread_mutex_lock(&count_mutex);

        --count;
        full = false;
        printf("consumer(%li):%i\n", pthread_self(), count);

        pthread_cond_broadcast(&cond_recv);
        pthread_mutex_unlock(&count_mutex);

        if((count >= MAX_ITEMS) {
            break;
        }
    }
}

 


CITS2002 Systems Programming, Lecture 21, p7, 10th October 2023.