Link to home
Create AccountLog in
Avatar of trubiat
trubiat

asked on

Producer/Consumer threads, semaphores and buffer problem

I am trying to initialize semaphores and use pthread_create in order to create new threads for the multiple producers and consumers. I am getting this type of error when I am trying to compile and I have no clue what it means because I it seems like my syntax is correct.

Also if anyone could give me some insight of how to create a Buffer that's accessible by producer and consumer functions and has size a parameter passed by the user. I am confused because the parameter is accessible by the main() function but the buffer has to be globally declared. I think malloc() has to be used but I don't know how.

Here is my code so far followed by the compilation errors I get:

#include <sys/types.h>
#include <sys/shm.h>
#include <sys/times.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_BUF_SIZE      255
#include <semaphore.h>

int *Buffer;
int maximum;
sem_t mut;
sem_t empty;
sem_t full;
void *producer(void *param);
void *consumer(void *param);

int main(int argc, char *argv[])
{
      pthread_t tid1, tid2;

      int i, r, PID, x;
      //int shmid, shmkey;
      //char *mem, *s;
      //char str [MAX_BUF_SIZE] = "Costas";
      int bufLength = (int)argv[2], max = (int)argv[1], pno = (int)argv[3], cno = (int)argv[4];
      maximum = max;
      //int buffer[2][bufLength * 2];

      if( !(argc == 4))
    {  
            printf("Wrong number of parameters. Please enter 4 parameters.\n");
            exit(1);
    }

      Buffer = (int*)malloc( (bufLength*sizeof(int)) * 2);
      sem_init(&mut, 0, 1);
      sem_init(&full, 0, 0);
      sem_init(&empty, 0, bufLength);

                  
                        for(i = 0; i < pno; i++)
                        {
                              PID = fork();
                              if (PID == 0)
                              {
                                    x = pthread_create(&tid1, NULL, producer, i);
                                    
                              }
                        }
                        if (PID != 0)
                        {
                              for(i = 0; i < cno; i++)
                              {
                                    if (fork() == 0)
                                    {
                                          x = pthread_create(&tid2, NULL, consumer, i);
                                          
                                    }
                              }
                        }
                  //}
                        exit(0);
                  
}

void *producer(void *param)
{
      int thread_num = atoi(param), a = 0;
      while (a == 0)
      {
            sem_wait(&mut);
            //buffer[0][1] = thread_num;
            sem_post(&mut);
      }
      printf("I am in CHILD PROCESS 1\n");
}

void *consumer(void *param)
{
      int thread_num = atoi(param), a = 0;
      while (a == 0)
      {
            sem_wait(&mut);
            //printf("%d\n", buffer[0][1]);
            sem_post(&mut);
      }
      printf("I am in CHILD PROCESS 1\n");
}


Errors:
/tmp/ccJh1ehp.o: In function `main':
test.c:(.text+0x84): undefined reference to `sem_init'
test.c:(.text+0x98): undefined reference to `sem_init'
test.c:(.text+0xad): undefined reference to `sem_init'
test.c:(.text+0xe7): undefined reference to `pthread_create'
test.c:(.text+0x132): undefined reference to `pthread_create'
/tmp/ccJh1ehp.o: In function `producer':
test.c:(.text+0x189): undefined reference to `sem_wait'
test.c:(.text+0x199): undefined reference to `sem_post'
/tmp/ccJh1ehp.o: In function `consumer':
test.c:(.text+0x1ed): undefined reference to `sem_wait'
test.c:(.text+0x1fd): undefined reference to `sem_post'
collect2: ld returned 1 exit status

Thank you all ofr your help.
Avatar of trubiat
trubiat

ASKER

Sorry, the fork() statements should be commented out. I am trying to use pthreads to create multiple threads for producers and consumers.

#include <sys/types.h>
#include <sys/shm.h>
#include <sys/times.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_BUF_SIZE      255
#include <semaphore.h>

int *Buffer;
int maximum;
sem_t mut;
sem_t empty;
sem_t full;
void *producer(void *param);
void *consumer(void *param);

int main(int argc, char *argv[])
{
      pthread_t tid1, tid2;

      int i, r, PID, x;
      //int shmid, shmkey;
      //char *mem, *s;
      //char str [MAX_BUF_SIZE] = "Costas";
      int bufLength = (int)argv[2], max = (int)argv[1], pno = (int)argv[3], cno = (int)argv[4];
      maximum = max;
      //int buffer[2][bufLength * 2];

      if( !(argc == 4))
    {  
            printf("Wrong number of parameters. Please enter 4 parameters.\n");
            exit(1);
    }

      Buffer = (int*)malloc( (bufLength*sizeof(int)) * 2);
      sem_init(&mut, 0, 1);
      sem_init(&full, 0, 0);
      sem_init(&empty, 0, bufLength);

                  
                        for(i = 0; i < pno; i++)
                        {
                              //PID = fork();
                              //if (PID == 0)
                              //{
                                    x = pthread_create(&tid1, NULL, producer, i);
                                    
                              //}
                        }
                        if (PID != 0)
                        {
                              for(i = 0; i < cno; i++)
                              {
                              //      if (fork() == 0)
                              //      {
                                          x = pthread_create(&tid2, NULL, consumer, i);
                                          
                              //      }
                              }
                        }
                  //}
                        exit(0);
                  
}

void *producer(void *param)
{
      int thread_num = atoi(param), a = 0;
      while (a == 0)
      {
            sem_wait(&mut);
            //buffer[0][1] = thread_num;
            sem_post(&mut);
      }
      printf("I am in CHILD PROCESS 1\n");
}

void *consumer(void *param)
{
      int thread_num = atoi(param), a = 0;
      while (a == 0)
      {
            sem_wait(&mut);
            //printf("%d\n", buffer[0][1]);
            sem_post(&mut);
      }
      printf("I am in CHILD PROCESS 1\n");
}
ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
>how to create a Buffer that's accessible by producer and consumer functions and has size a parameter passed by the user.
>I am confused because the parameter is accessible by the main() function but the buffer has to be globally declared.
>I think malloc() has to be used but I don't know how.

You are right .. you need to use malloc to allocate buffers at run time.

given size n bytes, you would allocate them as shown below.

my_pointer  = malloc (n);

malloc returns a void * and the address of newly allocated buffer of n bytes would be assigned to my_pointer. Also note that this buffer would remain in scope until you call free (my_pointer);
Till then this buffer can be accessed by all functions and it will remain in scope.

Let me know if you need some clarifications.

Cheers!
sunnycoder
Avatar of trubiat

ASKER

Thank you for your help sunnycoder,

So the buffer does not need to be declared globally?
you can either declare my_pointer globally and use it in all your functions ... or you can declare it in main and pass it as parameter to all functions that need it. I prefer the latter since I find it cleaner ... lesser the globals, better it is.

Cheers!
sunnycoder
Avatar of trubiat

ASKER

my pthread_create line creates segmentation fault. any idea why?

x = pthread_create(&tid1[i], NULL, producer, i+1);
>pthread_t tid1, tid2;
tid1 does not appear to be an array. Show me the exact code.
Avatar of trubiat

ASKER

The producer function never executes. I get segmentation fault within the for loop...Thanks for your help....I will accept your answer once this one has been answered..

Here is the exact code:

#include <sys/types.h>
#include <sys/shm.h>
#include <sys/times.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_BUF_SIZE      255
#include <semaphore.h>

int *Buffer;
int maximum;
sem_t mut;
sem_t empty;
sem_t full;
void *producer(void *param);
void *consumer(void *param);

int main(int argc, int *argv[])
{
      int i, r, PID, x;
      //int shmid, shmkey;
      //char *mem, *s;
      //char str [MAX_BUF_SIZE] = "Costas";
      int bufLength = atoi(argv[2]), max = atoi(argv[1]), pno = atoi(argv[3]), cno = atoi(argv[4]);
      pthread_t tid1, tid2;

      maximum = max;
      //int buffer[2][bufLength * 2];
      printf("max is %d, bufLength is %d, nProducers is %d, nConsumers is %d\n", max, bufLength, pno, cno);
      if( !(argc == 5))
    {  
            printf("Wrong number of parameters. Please enter 4 parameters.\n");
            exit(1);
    }

      Buffer = (int*)malloc( (bufLength*sizeof(int)) * 2);
      sem_init(&mut, 0, 1);
      sem_init(&full, 0, 0);
      sem_init(&empty, 0, bufLength);

                        for(i = 0; i < pno; i++)
                        {
                              //PID = fork();
                              //if (PID == 0)
                              //{
                                    x = pthread_create(&tid1, NULL, producer, i);
                                    
                              //}
                        }
                        //if (x != 0)
                        //{
                        //      for(i = 0; i < cno; i++)
                              //{
                              //      if (fork() == 0)
                              //      {
                        //                  x = pthread_create(&tid2, NULL, consumer, i);
                                          
                              //      }
                        //      }
                        //}
                  //}
                        exit(0);
                  
}

void *producer(void *param)
{
      int thread_num = atoi(param), a = 0;
      /*while (a == 0)
      {
            sem_wait(&mut);
            //buffer[0][1] = thread_num;
            sem_post(&mut);
      }*/
      printf("I am in PRODUCER with thread number: %d\n", thread_num);
}

void *consumer(void *param)
{
      int thread_num = atoi(param), a = 0;
      /*while (a == 0)
      {
            sem_wait(&mut);
            //printf("%d\n", buffer[0][1]);
            sem_post(&mut);
      }*/
      printf("I am in CONSUMER with thread number: %d\n", thread_num);
}

Call looks ok except that you are overwriting previous TIDs and you are not joining the threads .. so there is a resource leak.

Try checking the return values of each system call - malloc and pthread_create return the success/failure status. check it for error conditions.

Put printf as first line in producer and flush it before doing anything else.