livelock.c

DownloadView Raw

#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>


#define MAX 25 /* Numbers to produce */

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condc = PTHREAD_COND_INITIALIZER;
pthread_cond_t condp = PTHREAD_COND_INITIALIZER;

int processed = 0;
int buffer = 0;

void *producer_thread(void *ptr) {
    long counter = 0;
    int i;
    while (processed < MAX) {
        pthread_mutex_lock(&mutex);
        while (buffer != 0) {
            pthread_cond_wait(&condp, &mutex);
        }
        /* Time to produce a new value: */

        int r = rand();
        buffer = 0; /* Whoops, we have a bug here */
        /* Set buffer = r to fix */
        counter++;

        printf("[%ld] Buffer: %d\n", counter, buffer);
        /* Wake up consumer */
        pthread_cond_signal(&condc);
        pthread_mutex_unlock(&mutex);
    }

    return 0;
}

void *consumer_thread(void *ptr) {
    int i;

    for (i = 1; i <= MAX; i++) {
        pthread_mutex_lock(&mutex);
        while (buffer == 0) {
            pthread_cond_wait(&condc, &mutex);
        }
        printf("Consuming: %i\n", buffer);
        sleep(1);

        /* Set our buffer back to zero to indicate we processed it */
        buffer = 0;

        processed++;
        /* Wake up the producer */
        pthread_cond_signal(&condp);
        pthread_mutex_unlock(&mutex);
    }

    return 0;
}

int main(int argc, char **argv) {
    srand(time(NULL));
    pthread_t producer;
    pthread_t consumer;
    pthread_create(&producer, NULL, producer_thread, NULL);
    pthread_create(&consumer, NULL, consumer_thread, NULL);
    pthread_join(producer, NULL);
    pthread_join(consumer, NULL);
    return 0;
}