Producer/Consumer "produce" and "consume" function are not working - c

For the Producer/Consumer use semaphore in c language
Ask from user whether producer should run or consumer. Producer/consumer shouldn't call each other in your code. The call should be made explicitly from user only.
If producer is called to execute , the buffer should fill one slot. For consumer it should consume one slot.
Your code should make usage of bounded buffer. The capacity of buffer will be decided by user after execution of code.
For every producer/consumer call, the system should generate output how many filled slots are available and how many free slots are available in your buffer array.
Producer should be notified that it can't make more products if the array is full and consumer should be notified if there is no available slot to be consumed.
My produce and consume function are not working it just stucks after entering 'P' or 'C'
`
#include <stdio.h>
#include <semaphore.h>
#define MAX_BUFFER_SIZE 100
int buffer[MAX_BUFFER_SIZE];
int capacity;
int count = 0;
sem_t full;
sem_t empty;
sem_t mutex;
void produce() {
sem_wait(&empty);
sem_wait(&mutex);
buffer[count] = 1;
count++;
printf("Produced 1 item, %d slots available\n", capacity - count);
sem_post(&mutex);
sem_post(&full);
}
void consume() {
sem_wait(&full);
sem_wait(&mutex);
count--;
printf("Consumed 1 item, %d slots available\n", capacity - count);
sem_post(&mutex);
sem_post(&empty);
}
int main() {
sem_init(&full, 0, 0);
sem_init(&empty, 0, capacity);
sem_init(&mutex, 0, 1);
printf("Enter capacity of buffer: ");
scanf("%d", &capacity);
char choice;
while (1) {
printf("Enter P to produce or C to consume: ");
scanf(" %c", &choice);
if (choice == 'P') {
produce();
} else if (choice == 'C') {
consume();
} else {
break;
}
}
sem_destroy(&full);
sem_destroy(&empty);
sem_destroy(&mutex);
return 0;
}
`
I tried to enter 'p' or 'C' it just does nothing
Terminal Output it just stuck

Related

Only three of my five threads are executing, synchronizing using mutexes

I am doing an academic exercise for an OS class where we synchronize five detached threads using ONLY mutex locks and unlocks. We "CANNOT force the threads into any serial execution. Once spawned they must be free from external influences (other than the mutexes). The parent should NOT employ a pthread_join."
I am spawning 5 threads, detaching them and then using each threads to read in data and update a global variable. Currently my code spawns the 5 threads but only three of them output their ID's and none of them get into the while loop. Any help/advice here would be appreciated!
Output:
thread: 6156515168
thread: 6156515192
thread: 6156515176
There is a sleep in main which if uncommented provides the expected output, but this would be forcing a serial execution..
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <pthread.h>
pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER; // declaring mutex
int FileNameHelper=1;
int balance=0;
void* detatchedThread(void *param){
long tid = (long)param;
char* base = "data";
char filename[256];
char buf[100];
sprintf(filename, "%s%d.in", base, FileNameHelper); //creates data1.in, data2.in...
FileNameHelper ++;
FILE *inputFile = fopen(filename, "r");
printf ("thread: %ld\n", tid);
// critical sec line
if(fgets(buf, sizeof buf, inputFile) == NULL)
return NULL; // could not read first line
sleep(1); // make sure each thread runs long enough to get the random update behavior required.
pthread_mutex_lock(&mutex_lock); //we are in the critical section, lock mutex
while(fgets(buf, sizeof buf, inputFile) != NULL) {
int val;
if(sscanf(buf, "%d", &val) != 1){
break;
}
printf("%d\n", val);
balance += val;
printf ("Account balance after thread %ld is $%d\n", tid, balance);
}
pthread_mutex_unlock(&mutex_lock);
if(buf[0] != 'W')
return NULL;// last line data was invalid
pthread_exit(NULL);
}
int main(){
pthread_t th[5];
//initialize the mutex
if(pthread_mutex_init(&mutex_lock, NULL) != 0){
printf("\nmutex init has failed\n");
return 1;
}
//call the 5 threads, Detach the threads once they are created.
for (int i = 0; i < 5; i++){
pthread_create(&th[i], NULL, detatchedThread, (void *)&th[i]);
pthread_detach(th[i]);
//sleep(1); uncommenting this line gives me the expected behavior
}
pthread_mutex_destroy(&mutex_lock);
return 0;
}

How to avoid worker threads being stuck in sem_wait?

I am new to semaphores and wanted to know how to avoid a situation where my worker thread (in a multiple worker single producer problem) is stuck in sem_wait(&full). I also have a mutex lock after this but I doubt that, that is where it is stuck. I know all my tasks are being completed but the threads are not exiting. The producer thread in my program stops sending data once all tasks are done.
For reference... the producer thread...
while (i<number_of_tasks)
{
TASK task;
task.start_row = i*num_of_rows;
task.num_of_rows = num_of_rows;
sem_wait(&empty);
pthread_mutex_lock(&mutex);
tasks[in] = task;
in = (in+1)%buff_size;
pthread_mutex_unlock(&mutex);
sem_post(&full);
i++;
//printf("%d tasks completed out of %d tasks\n", counter, number_of_tasks);
if (counter==number_of_tasks)
break;
}
And ...the worker thread function
int i, item, index;
TASK task;
index = *((int*)arg);
int notasks1;
for (i=number_of_tasks; i > 0; i--) {
//previous code
sem_wait(&full);
pthread_mutex_lock(&mutex);
task=tasks[out];
out = (out+1)%buff_size;
//completing task code...
counter++;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
printf("%d tasks completed out of %d tasks\n", counter, number_of_tasks);
if (counter==number_of_tasks)
break;
}
printf("Worker thread %d has terminated and completed %d tasks\n",index,notasks1);
return NULL;
the full code... for reference
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/semaphore.h>
// for sleep
#include <unistd.h>
#include "Mandel.h"
#include "draw.h"
#define BUFF_SIZE 10 /* total number of slots */
#define NP 1 /* total number of producers */
#define NC 5 /* total number of consumers */
#define NITERS IMAGE_HEIGHT/10 /* number of items produced/consumed */
//int buf[BUFF_SIZE]; /* shared var */
//struct task for storing the tasks the current worker thread has to do
typedef struct task
{
int start_row;
int num_of_rows;
} TASK;
TASK* tasks;
int buff_size; //= 7;
//TASK buff[buff_size];
int in=0; /* buf[in%BUFF_SIZE] is the first empty slot */
int out=0; /* buf[out%BUFF_SIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
int number_of_tasks;// = IMAGE_HEIGHT/20;
float *pixels;
int num_of_rows;// = 20;
int counter = 0;
// use correct type here
pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
/*void *Producer(void *arg)
{
int i =0;
while (i<number_of_tasks)
{
if (counter==number_of_tasks)
break;
TASK task;
task.start_row = i*num_of_rows;
task.num_of_rows = num_of_rows;
sem_wait(&empty);
pthread_mutex_lock(&mutex);
tasks[in] = task;
in = (in+1)%buff_size;
pthread_mutex_unlock(&mutex);
sem_post(&full);
i++;
if (counter==number_of_tasks)
break;
}
return NULL;
}*/
//function for consumer threads to accesss
void *Consumer(void *arg)
{
int i, item, index;
TASK task;
index = *((int*)arg);//getting index of thread from argument parsing it into int
int notasks1;
//for loop to complete number of tasks per thread
for (i=number_of_tasks; i > 0; i--) {
//defining start_compute and end compute to calculate time per task
struct timespec start_compute, end_compute;
float difftime;
printf("Worker(%d): Start the computation ...\n", index);
clock_gettime(CLOCK_MONOTONIC, &start_compute);
//calling sem wait to wait for producer thread to fill in tasks for worker threads. will wait if buffer is empty
sem_wait(&full);
//calling mutex lock
pthread_mutex_lock(&mutex);
//getting tasks from struct tasks array
task=tasks[out];
//incrementing to next task in buffer so that next thread accesses next task
out = (out+1)%buff_size;
//calculating pixels for image
int x, y;
//printf("start_row... %d, num_of_rows... %d\n", task.start_row, task.num_of_rows);
for (y=task.start_row; y<task.start_row+task.num_of_rows; y++)
{
for (x=0; x<IMAGE_WIDTH; x++)
{
pixels[y*IMAGE_WIDTH+x] = Mandelbrot(x, y);
}
}
//increasing counter to check if all tasks are done
counter++;
pthread_mutex_unlock(&mutex);
sem_post(&empty);//informing a producer that a task has been taken out and if tasks are left buffer is empty to add tasks
//calculating end compute and posting
clock_gettime(CLOCK_MONOTONIC, &end_compute); //end time values for the child processes
difftime = (end_compute.tv_nsec - start_compute.tv_nsec)/1000000.0 + (end_compute.tv_sec - start_compute.tv_sec)*1000.0;
printf("Worker(%d):\t...completed. Elapse time = %f ms\n",index, difftime);\
notasks1++;
printf("%d tasks completed out of %d tasks\n", counter, number_of_tasks);
if (counter==number_of_tasks)
break;
}
printf("Worker thread %d has terminated and completed %d tasks\n",index,notasks1);
return NULL;
}
int main(int argc, char* args[])
{
buff_size = atoi(args[3]);
num_of_rows = atoi(args[2]);
number_of_tasks = IMAGE_HEIGHT/num_of_rows;
int number_of_workers;
number_of_workers = atoi(args[1]);
struct timespec start_time, end_time;
printf("number_of_tasks...%d\n", number_of_tasks);
pthread_t idP, idC;
int index;
sem_init(&full, 0, 0);//initializing full to zero so that consumer thread knows buffer is empty and waits for producer thread
sem_init(&empty, 0, buff_size);//initializing empty to buffer size so that producer knows to add that many tasks
pthread_mutex_init(&mutex, NULL);
int i = 0;
pixels = (float *) malloc(sizeof(float) * IMAGE_WIDTH * IMAGE_HEIGHT);//assigning pixels memory
//tasks = (TASK*) malloc (sizeof(TASK) *buff_size);
//pthread_create(&idP, NULL, Producer, NULL);
for(index=0; index<number_of_workers/*5*/; index++)
{
printf("Worker(%d): Start up. Wait for task!\n", index);
pthread_create(&idC, NULL, Consumer, (void*)&index);//creating worker threads to go to consumer function sending their index
}
tasks = (TASK*) malloc (sizeof(TASK) *buff_size);
//master/producer thread work
while (i<number_of_tasks)
{
TASK task;
task.start_row = i*num_of_rows;
task.num_of_rows = num_of_rows;
//calling sem wait if buffer is not empty
sem_wait(&empty);
pthread_mutex_lock(&mutex);
//adding tasks to struct task tasks array for worker/consumer threads to use
tasks[in] = task;
in = (in+1)%buff_size;
pthread_mutex_unlock(&mutex);
sem_post(&full);
//incrementing full so that worker threads know that buffer is not empty
i++;
//printf("%d tasks completed out of %d tasks\n", counter, number_of_tasks);
if (counter==number_of_tasks)
break;
}
//pthread_exit(NULL);
//waiting for all threads to exit
//pthread_join(idC, NULL);
//printing image
printf("Draw the image\n");
DrawImage(pixels, IMAGE_WIDTH, IMAGE_HEIGHT, "Mandelbrot demo", 3000);
return 0;
}
How to stop the worker thread from being stuck in the loop?
I know the program continues on and displays the correct result but when I call pthread_join it keeps on waiting... obviously. How to solve the issue?

producer consumer using posix

I have a Standard Producer Consumer problem for bounded buffer.Whenever i give unequal number of producer or consumer the Program does not terminate.
I have limited the number of insertion or deletion to 50
I would like to know why the above problem occurs and ways to fix it
#include<stdio.h>
#include<pthread.h> //Header for creating Posix Threads;
#include<semaphore.h>
#include<stdlib.h>
#define MAX 20
typedef struct shared_buffer
{
int arr[20];
int i;
}buffer;
buffer b; //Fixed Length buffer shared memory
sem_t full,empty; //Counting semaphores full->no of slots filled empty ->no of slots empty
pthread_mutex_t mutex; //mutual exclusion for critcal section
int flag=1,cnt=0;
void * producer(void * arg) //Producer threads method
{
int index; //thread Id
index=(int)arg;
while(flag)
{
sem_wait(&empty); //will check if slot available and decrement empty count
pthread_mutex_lock(&mutex); //acquiring lock on process
b.arr[b.i]=rand()%100; //critcal section
printf("\n Process %d Produced :%d",index,b.arr[b.i]);
b.i++;
cnt++; //critcal section ends
pthread_mutex_unlock(&mutex); //realeasing lock
sem_post(&full); //increment full count
usleep(rand()%100); //sleep for random time
}
}
void * consumer(void * arg)
{
int index;
index=(int)arg;
while(flag)
{
sem_wait(&full); //will check if buffer is not empty
pthread_mutex_lock(&mutex);
b.i--; //critical section
printf("\n Process %d consumed :%d",index,b.arr[b.i]);
cnt++; //critical section ends
pthread_mutex_unlock(&mutex); //release lock
sem_post(&empty); //increment count of empty slots
usleep(rand()%100);
}
}
int main(int argc,char * argv[])
{
pthread_t Pid,Cid;
int P,C,index,size;
b.i=0;
if(argc<4)
{
printf("Error.Usage : ./filename.out <no of producer> <no of consumer> <Buffer Size(<=15)> \n");
exit(0);
}
P=atoi(argv[1]);
C=atoi(argv[2]);
size=atoi(argv[3]);
sem_init(&full,0,0); //number of slots filled is 0
sem_init(&empty,0,size); //number of empty slots is buffer size
pthread_mutex_init(&mutex,NULL);
for (index=0;index<C;index++) //creating C number of consumer
{
pthread_create(&Cid,NULL,consumer,index);
}
for (index=0;index<P;index++) //creating P number of producer
{
pthread_create(&Pid,NULL,producer,index);
}
while(cnt<=50) //maximum 50 operations allowed
usleep(200);
flag=0;
printf("phew!Successful");
pthread_exit(NULL);
return 1;
}
Here are some clues (not full answer):
First thing that bugging me is that you are overwriting your pthread_t references in your loops. But it is OK since you don't use them afterwards.
Second thing is that you misplaced the pthread_exit: there should be at the end of the threads you created:
void * consumer_producer(void * arg)
{
// ...
while(flag)
{
// ...
}
pthread_exit(NULL);
}
I guess you have a race condition. It is possible that a thread is waiting when flag is set to 0. Other threads possibly catch that state and return, thus the waiting thread is waiting forever.

Sleeping barber using semaphore

I am having a problem in the synchronisation of threads. I m trying to implement sleeping barber problem in a different approach.
When i run the code the threads run in a completely vague manner.
When i add join to the threads the processes run one by one which is not required.
I know the solutions to the sleeping barber problem but can anybody tell me what is the problem with this code.?
Thank You
#include<stdio.h>
#include<pthread.h>
#include<time.h>
#include <unistd.h>
#include<semaphore.h>
#define n 1
#define n1 50
int status[n];
int b=0;
sem_t mutex;
sem_t barber;
void *barb()
{
printf("Barber Sleeping\n");
b=1;
sem_wait(&barber);
printf("Barber woke up\n");
sleep(1);
b=0;
}
void *handler(void *ptr)
{
int x;
x = *((int *) ptr);
int flag=0;
int i=0;
int cnt=0;
for(i=0;i<n;i++)
{
if(status[i]==1)
{
flag=1;
cnt++;
}
}
printf("Count=%d",cnt);
if(cnt==n)
{
printf("%d Customer Returned\n",x);
return 0;
}
if(flag==1)
{
status[x]=1;
printf("%d Customer waiting\n",x);
sem_wait(&mutex);
}
if(b==1)
{
printf("Customer %d woke up barber",x);
sem_post(&barber);
}
printf("Cutting Hair of customer %d\n",x);
status[x]=1;
sleep(5);
flag=0;
for(i=0;i<n;i++)
{
if(status[i]==1)
{
flag=1;
}
}
status[x]=0;
printf("Finished cutting Hair of customer %d\n",x);
if(flag==1)
sem_post(&mutex);
}
int main()
{
sem_init(&mutex, 0, n);
sem_init(&barber, 0, 1);
pthread_t thread[n1];
pthread_t barber;
int i=0;
for(i=0;i<n;i++)
{
status[i]=0;
}
pthread_create(&barber,NULL,barb,NULL);
pthread_join(barber,NULL);
for(i=0;i<n1;i++)
{
sleep(1);
printf("Customer entered %d\n",i);
pthread_create(&thread[i], NULL, handler, (void *)&i);
//pthread_join(thread[i],NULL);
}
for(i=0;i<n1;i++)
{
//pthread_join(thread[i],NULL);
}
//sem_post(&barber);
}
I have the code to help you
#define _REENTRANT
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
// The maximum number of customer threads.
#define MAX_CUSTOMERS 25
// Function prototypes...
void *customer(void *num);
void *barber(void *);
void randwait(int secs);
// Define the semaphores.
// waitingRoom Limits the # of customers allowed
// to enter the waiting room at one time.
sem_t waitingRoom;
// barberChair ensures mutually exclusive access to
// the barber chair.
sem_t barberChair;
// barberPillow is used to allow the barber to sleep
// until a customer arrives.
sem_t barberPillow;
// seatBelt is used to make the customer to wait until
// the barber is done cutting his/her hair.
sem_t seatBelt;
// Flag to stop the barber thread when all customers
// have been serviced.
int allDone = 0;
int main(int argc, char *argv[]) {
pthread_t btid;
pthread_t tid[MAX_CUSTOMERS];
long RandSeed;
int i, numCustomers, numChairs;
int Number[MAX_CUSTOMERS];
// Check to make sure there are the right number of
// command line arguments.
if (argc != 4) {
printf("Use: SleepBarber <Num Customers> <Num Chairs> <rand seed>\n");
exit(-1);
}
// Get the command line arguments and convert them
// into integers.
numCustomers = atoi(argv[1]);
numChairs = atoi(argv[2]);
RandSeed = atol(argv[3]);
// Make sure the number of threads is less than the number of
// customers we can support.
if (numCustomers > MAX_CUSTOMERS) {
printf("The maximum number of Customers is %d.\n", MAX_CUSTOMERS);
exit(-1);
}
printf("\nSleepBarber.c\n\n");
printf("A solution to the sleeping barber problem using semaphores.\n");
// Initialize the random number generator with a new seed.
srand48(RandSeed);
// Initialize the numbers array.
for (i=0; i<MAX_CUSTOMERS; i++) {
Number[i] = i;
}
// Initialize the semaphores with initial values...
sem_init(&waitingRoom, 0, numChairs);
sem_init(&barberChair, 0, 1);
sem_init(&barberPillow, 0, 0);
sem_init(&seatBelt, 0, 0);
// Create the barber.
pthread_create(&btid, NULL, barber, NULL);
// Create the customers.
for (i=0; i<numCustomers; i++) {
pthread_create(&tid[i], NULL, customer, (void *)&Number[i]);
}
// Join each of the threads to wait for them to finish.
for (i=0; i<numCustomers; i++) {
pthread_join(tid[i],NULL);
}
// When all of the customers are finished, kill the
// barber thread.
allDone = 1;
sem_post(&barberPillow); // Wake the barber so he will exit.
pthread_join(btid,NULL);
}
void *customer(void *number) {
int num = *(int *)number;
// Leave for the shop and take some random amount of
// time to arrive.
printf("Customer %d leaving for barber shop.\n", num);
randwait(5);
printf("Customer %d arrived at barber shop.\n", num);
// Wait for space to open up in the waiting room...
sem_wait(&waitingRoom);
printf("Customer %d entering waiting room.\n", num);
// Wait for the barber chair to become free.
sem_wait(&barberChair);
// The chair is free so give up your spot in the
// waiting room.
sem_post(&waitingRoom);
// Wake up the barber...
printf("Customer %d waking the barber.\n", num);
sem_post(&barberPillow);
// Wait for the barber to finish cutting your hair.
sem_wait(&seatBelt);
// Give up the chair.
sem_post(&barberChair);
printf("Customer %d leaving barber shop.\n", num);
}
void *barber(void *junk) {
// While there are still customers to be serviced...
// Our barber is omnicient and can tell if there are
// customers still on the way to his shop.
while (!allDone) {
// Sleep until someone arrives and wakes you..
printf("The barber is sleeping\n");
sem_wait(&barberPillow);
// Skip this stuff at the end...
if (!allDone) {
// Take a random amount of time to cut the
// customer's hair.
printf("The barber is cutting hair\n");
randwait(3);
printf("The barber has finished cutting hair.\n");
// Release the customer when done cutting...
sem_post(&seatBelt);
}
else {
printf("The barber is going home for the day.\n");
}
}
}
void randwait(int secs) {
int len;
// Generate a random number...
len = (int) ((drand48() * secs) + 1);
sleep(len);
}

Semaphores and Deadlocks in C

I'm trying to code the producer/consumer problem using semaphores. I have 3, 1 acting as a mutex, and another 2 for the buffer which the producers and consumers can add/remove from. When adding/removing from the buffer I use the binary semaphore to lock/unlock it so that the global variables aren't subject to any race conditions. The produce semaphore represents how many spots are available in the buffer (how many things can be put into the buffer) while the consumer semaphore represents how many things can be removed from the buffer. I think my logic is wrong cause I always reach a deadlock. Also when I removed the produce and consume semaphores just to test whether or not the program does what its supposed to do, I still get race conditions even though the binary semaphore should be blocking that. What am I doing wrong?
enter code here
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <pthread.h>
#include </usr/include/semaphore.h>
#define MAXITEMS 100
#define PRODUCER_NO 5
#define NUM_PRODUCED 5
void *producer_function (void);
void *consumer_function (void);
void add_buffer (long i);
long get_buffer ();
long sum_value = 0;
long finished_producers;
long buffer[MAXITEMS];
int size = 0;
int front, rear = 0;
pthread_t producerThread[5];
pthread_t consumerThread;
sem_t mutex, produce, consume;
int main(void)
{
int i = 0;
srand (time(NULL));
sem_init (&mutex, 0, 1);
sem_init (&produce, 0, 100);
sem_init (&consume, 0, 0);
for (i = 0; i < 5; i++)
{
pthread_create (&producerThread[i], NULL, (void *) producer_function, NULL);
}
pthread_create (&consumerThread, NULL, (void *) consumer_function, NULL);
for (i = 0; i < 5; i++)
{
pthread_join (producerThread[i], NULL);
}
pthread_join (consumerThread, NULL);
return(0);
}
void *producer_function(void)
{
long counter = 0;
long producer_sum = 0L;
while (counter < NUM_PRODUCED)
{
sem_wait (&mutex);
sem_wait (&produce);
long rndNum = rand() % 10;
producer_sum += rndNum;
add_buffer (rndNum);
sem_post (&consume);
counter++;
if (counter == NUM_PRODUCED)
{
finished_producers++;
}
sem_post (&mutex);
usleep(1000);
}
printf("--+---+----+----------+---------+---+--+---+------+----\n");
printf("The sum of produced items for this producer at the end is: %ld \n", producer_sum);
printf("--+---+----+----------+---------+---+--+---+------+----\n");
return(0);
}
void *consumer_function (void)
{
while (1)
{
sem_wait (&mutex);
sem_wait (&consume);
long readnum = get_buffer();
sem_post (&produce);
sum_value += readnum;
sem_post (&mutex);
//printf ("%ld\n", sum_value);
if ((finished_producers == PRODUCER_NO) && (size == 0))
{
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("The sum of the all produced items at the end is: %ld \n", sum_value);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
break;
}
}
}
void add_buffer(long i){
buffer[rear] = i;
rear = (rear+1) % MAXITEMS;
size++;
}
long get_buffer(){
long v;
v = buffer[front];
front = (front+1) % MAXITEMS;
size--;
return v;
}
user2929779,
I think its essential to not have the mutex locked, when waiting for a consume notification in the consumer, or vice versa a produce notification in the producer. Imagine you're getting blocked because of waiting for a consume notification, and no producer was able to publish such a notification then your consumer keeps the mutex locked and no producer ever gets the chance to produce a new item...
So the order is important here:
1.) First wait for notification from remote side
2.) lock mutex
3.) modify global data
4.) release mutex
5.) notify remote side
Try this instead:
void *producer_function(void)
{
long counter = 0;
long producer_sum = 0L;
while (counter < NUM_PRODUCED)
{
sem_wait (&produce);
sem_wait (&mutex);
long rndNum = rand() % 10;
producer_sum += rndNum;
add_buffer (rndNum);
counter++;
if (counter == NUM_PRODUCED)
{
finished_producers++;
}
sem_post (&mutex);
sem_post (&consume);
usleep(1000);
}
printf("--+---+----+----------+---------+---+--+---+------+----\n");
printf("The sum of produced items for this producer at the end is: %ld \n", producer_sum);
printf("--+---+----+----------+---------+---+--+---+------+----\n");
return(0);
}
void *consumer_function (void)
{
while (1)
{
sem_wait (&consume);
sem_wait (&mutex);
long readnum = get_buffer();
sum_value += readnum;
if ((finished_producers == PRODUCER_NO) && (size == 0))
{
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("The sum of the all produced items at the end is: %ld \n", sum_value);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
break;
}
sem_post (&mutex);
sem_post (&produce);
//printf ("%ld\n", sum_value);
}
return(0);
}
P.S. For now ignoring return values of system calls just to show example implementation...
P.S.S. See also pseudo code on wiki http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Using_semaphores ...

Resources