• C

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.
trubiatAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

trubiatAuthor Commented:
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");
}
0
sunnycoderCommented:
Hi trubiat,

compile your code with -lpthread flag in the command line

Cheers!
Sunnycoder
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sunnycoderCommented:
>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
0
Become a Leader in Data Analytics

Gain the power to turn raw data into better business decisions and outcomes in your industry. Transform your career future by earning your MS in Data Analytics. WGU’s MSDA program curriculum features IT certifications from Oracle and SAS.  

trubiatAuthor Commented:
Thank you for your help sunnycoder,

So the buffer does not need to be declared globally?
0
sunnycoderCommented:
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
0
trubiatAuthor Commented:
my pthread_create line creates segmentation fault. any idea why?

x = pthread_create(&tid1[i], NULL, producer, i+1);
0
sunnycoderCommented:
>pthread_t tid1, tid2;
tid1 does not appear to be an array. Show me the exact code.
0
trubiatAuthor Commented:
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);
}

0
sunnycoderCommented:
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.