Mounir
Mounir

Reputation: 155

Why my producer-consumer program in C not working properly?

I'm trying to synchronize 02 child processes that communicate using a buffer of size 5 using the semaphores "empty" and "full" only. Process 01 executes producer() function and the second one executes consumer(), but the consumer functions does not execute at all even when the producer is blocked (empty=0). after 5 iterations, I only get 5 insertions but no consuming ( I'm inserting 5's for now). Also I believe there is no need for a mutex since there are only 01 producer and 01 consumer right? here are the 02 functions and the main program:

#include <semaphore.h>
#include <stdlib.h>
#include <stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include <pthread.h>

#define MaxItems 5 
#define BufferSize 5 

sem_t empty;
sem_t full;

//pthread_mutex_t lock;

int in = 0;
int out = 0;
int buffer[BufferSize];
int N = 20;

void *producer()
{   
    while(1)
    {
        //pthread_mutex_lock(&lock);
        sem_wait(&empty);
    
        buffer[in] = 5; // fill the buffer with numbers
        printf("\nInsert Item %d at %d\n", buffer[in],in);

        int emptyvalue, fullValue;
        sem_getvalue(&full, &fullValue); sem_getvalue(&empty, &emptyvalue);
        printf("full is:%d, empty is:%d\n", fullValue, emptyvalue);

        //pthread_mutex_unlock(&lock);  
        sem_post(&full); // increase the value of full, so the consumer should execute now?
        in = (in+1)%BufferSize;
        usleep(500000);
    } 
}

void *consumer()
{   
    printf("test: consumer"); //this consumer function does not execute
    
    while (1)
    {
        sem_wait(&full); // full initially is = 0, so it blocks at first
        //pthread_mutex_lock(&lock);
       
        int item = buffer[out];
        printf("Remove Item %d from %d\n",item, out);
        
        //pthread_mutex_unlock(&lock);
        sem_post(&empty);

        printf(" %d", out); //using the values in the buffer
        out = (out+1)%BufferSize;
    }
}

int main()
{   
    //pthread_mutex_init(&lock, NULL);
    sem_init(&empty,0,BufferSize);
    sem_init(&full,0,0);

    pid_t id1, id2;

    id1 = fork();
    if (id1 == 0) {
      
        id2 = fork();
        if (id2 == 0) //child 2
        {
            printf("im the consumer");
            consumer();
        }else{ //child 1
            printf("i'm the producer");
            producer();
        }
    }else{
        sem_destroy(&full);
        sem_destroy(&empty);
        //pthread_mutex_destroy(&lock);
        return 0;
    }
}

thank you so much

Upvotes: 0

Views: 227

Answers (1)

ElderBug
ElderBug

Reputation: 6145

By default, different processes live in different virtual address spaces. They cannot access each other's memory. The same is true for POSIX semaphores. This means that when you use fork to make two processes, you end up with two different sets of variables. You have a separate buffer and semaphores for each process.

To make this work, you should create a memory mapping (mmap for POSIX) where you put all the data you need to share between the processes, including the semaphores. The semaphores should be initialized with pshared to non-zero. The man page for sem_init has more details about this.

Alternatively you could use some other form of inter-process communication, like pipes.

Upvotes: 1

Related Questions