Search code examples
cproducer-consumer

Producer-Consumer solution runs but doesn't print


This is my current code for the Producer-Consumer problem. I compiled it and ran it but nothing is printed. The command line takes in 3 arguments: Sleep time, producer threads, consumer threads. I've tried setting the values as 5, 1, 1 respectively, the sleep timer works but I'm unsure about the rest.

Code for buffer.h:

typedef int buffer_item;

#define BUFFER_SIZE 5

Code for buffer.c:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"

buffer_item buffer[BUFFER_SIZE];
void *producer(void *param);
void *consumer(void *param);

pthread_mutex_t mutex;
sem_t empty;
sem_t full;


int insert_item(buffer_item item)
{
    do
    {
        wait(empty);
        wait(mutex);

        signal(mutex);
        signal(full);
    }while(1);

    return 0;
}

int remove_item(buffer_item *item)
{
    do
    {
        wait(full);
        wait(mutex);

        signal(mutex);
        signal(empty);
    }while(1);

    return 0;
}

int main(int argc, char *argv[])
{
    int sleepTime;
    int producerThreads;
    int consumerThreads;

    int counter_1;
    int counter_2;

    if(argc != 4)
    {
        return -1;
    }

    sleepTime = atoi(argv[1]);
    producerThreads = atoi(argv[2]);
    consumerThreads = atoi(argv[3]);

    srand((unsigned)time(NULL));

    for(counter_1 = 0; counter_1 < producerThreads; counter_1++)
    {
        pthread_t tid;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&tid, &attr, producer, NULL);
    }

    for(counter_2 = 0; counter_2 < consumerThreads; counter_2++)
    {
        pthread_t tid;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&tid, &attr, consumer, NULL);
    }

    sleep(sleepTime);

    return 0;
}

void *producer(void *param)
{
    buffer_item item;
    int randomTime;
    int counter_1 = 0;

    while(1)
    {
        randomTime = rand() % 1000 + 1;
        sleep(randomTime);

        item = rand();

        if(insert_item(item))
        {
            fprintf(stderr, "Error.");
        }
        else
        {
            printf("Producer ID: %lu, Produced Item: %d\n", pthread_self(), item);
            printf("The buffer now contains %d items\n", counter_1);
            ++counter_1;
        }
    }

}

void *consumer(void *param)
{
    buffer_item item;
    int randomTime;
    int counter_2 = 0;

    while(1)
    {
        randomTime = rand() % 1000 + 1;
        sleep(randomTime);

        if(insert_item(item))
        {
            fprintf(stderr, "Error.");
        }
        else
        {
            printf("Consumer ID: %lu, Consumed Item: %d\n", pthread_self(), item);
            printf("The buffer now contains %d items\n", counter_2);
            ++counter_2;
        }
    }
}

So far I've tried declaring the tid separately, skipping sleep and join the threads, but it still doesn't print.


Solution

  • Your code can't possibly run, indeed it doesn't even compile. Here's a list of issues that need to be addressed:

    • wait should be sem_wait
    • signal should be sem_post for semaphores
    • int sem_wait(sem_t *sem); and int sem_post(sem_t *sem); take the pointer to a semaphore
    • sem_wait(mutex) and sem_post(mutex) give something like "incompatible type for argument 1 of sem_wait", I guess you want to acquire and release the lock on the mutex like pthread_mutex_lock(&mutex) and pthread_mutex_unlock(&mutex)
    • in the consumer if(insert_item(item)): item is used uninitialized
    • still in the consumer you use insert_item instead of remove_item

    Coming to the main question "I compiled it and ran it but nothing is printed", it doesn't print anything because producer and consumer call, respectively, insert_item and remove_item and are trapped inside infinite loops (e.g. while(1))