I'd like to have two threads, a producer and a consumer, which continuously fill and empty a shared buffer. The code is a little pedantic, but I'm going to expand on it later to include actual stop conditions. Here is my situation: I have started the producer thread, it fills the buffer, passes control to the consumer, and the consumer empties the buffer. However, the consumer does not pass control back to the producer to refill the buffer. What do I have to change in order for the producer and consumer threads to continuously fill, empty, and refill the shared buffer?
Here is how my code is set up:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX 10
int buffer[MAX];
int count = 0;
pthread_mutex_t mutex;
pthread_cond_t dataAvailable;
pthread_cond_t spaceAvailable;
void *consumer(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
while(count == 0)
{
pthread_cond_signal(&spaceAvailable);
printf("Signaling spaceAvailable\n");
pthread_cond_wait(&dataAvailable,&mutex);
printf("Consumer: resume after the wait\n");
}
sleep(1);
printf("starting to empty the buffer...\n");
int j;
for(j = 0; j < MAX; j++)
{
buffer[j] = 0;
printf("Consumer: buffer[%d] = %d\n",j,buffer[j]);
--count;
}
pthread_cond_signal(&spaceAvailable);
printf("The value of count is: %d\n",count);
pthread_cond_wait(&dataAvailable,&mutex);
}
}
void *producer(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
while(count == 9)
{
pthread_cond_signal(&dataAvailable);
printf("Signaling dataAvailable\n");
pthread_cond_wait(&spaceAvailable,&mutex);
printf("Producer: resume after wait\n");
}
sleep(1);
printf("starting to load the buffer...\n");
int j;
for(j = 0; j < MAX; j++)
{
buffer[j] = j;
printf("Producer: buffer[%d] = %d\n",j,buffer[j]);
++count;
}
pthread_cond_signal(&dataAvailable);
pthread_cond_wait(&spaceAvailable,&mutex);
}
}
int main(int argc, char *argv[])
{
pthread_t thread;
pthread_create(&thread,0,producer,NULL);
pthread_create(&thread,0,consumer,NULL);
pthread_exit(0);
}
This is what my output looks like:
starting to load the buffer...
Producer: buffer[0] = 0
Producer: buffer[1] = 1
Producer: buffer[2] = 2
Producer: buffer[3] = 3
Producer: buffer[4] = 4
Producer: buffer[5] = 5
Producer: buffer[6] = 6
Producer: buffer[7] = 7
Producer: buffer[8] = 8
Producer: buffer[9] = 9
starting to empty the buffer...
Consumer: buffer[0] = 0
Consumer: buffer[1] = 0
Consumer: buffer[2] = 0
Consumer: buffer[3] = 0
Consumer: buffer[4] = 0
Consumer: buffer[5] = 0
Consumer: buffer[6] = 0
Consumer: buffer[7] = 0
Consumer: buffer[8] = 0
Consumer: buffer[9] = 0
The value of count is: 0
I'd like to have the Producer and Consumer statements to print every second. What would I have to fix in order to make that happen?
Use semaphore to synchronize (signal the other thread when one has executed the iteration):
Semaphore s1, s2;
Producer:
P(&s1)
// do your operations
print()
V(&s2) //unlock the consumer thread
Consumer:
P(&s2)
// do your operations
print()
V(&s1) //unlock the producer thread
Just make sure you do it in such a way to avoid any deadlock.