The producer–consumer problem is an example of a
multi-process synchronization problem. The problem describes two processes, the
producer and the consumer, who share a common, fixed-size buffer used as a
queue. The producer's job is to generate data, put it into the buffer, and
start again. At the same time, the consumer is consuming the data , one piece
at a time. The problem is to make sure that the producer won't try to add data
into the buffer if it's full and that the consumer won't try to remove data from
an empty buffer. Here is an implementation of the problem using pthreads. The
producer and consumer running as separate threads will move items to and from a
buffer.
/*
* Solution to Producer Consumer Problem
* Using Ptheads, a mutex and condition variables
*/
/*
In this version the buffer is a single number.
The producer is putting numbers into the shared buffer
And the consumer is taking them out.
If the buffer contains zero, that indicates that the buffer is empty.
*/
#include <stdio.h>
#include <pthread.h>
#define MAX 10000000000 /* Numbers to produce */
pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
int buffer = 0;
void* producer(void *ptr) {
int i;
for (i = 1; i <= MAX; i++) {
pthread_mutex_lock(&the_mutex); /* protect buffer */
while (buffer != 0) /* If there is something
in the buffer then wait */
pthread_cond_wait(&condp, &the_mutex);
buffer = i;
pthread_cond_signal(&condc); /* wake up consumer */
pthread_mutex_unlock(&the_mutex); /* release the buffer */
}
pthread_exit(0);
}
void* consumer(void *ptr) {
int i;
for (i = 1; i <= MAX; i++) {
pthread_mutex_lock(&the_mutex); /* protect buffer */
while (buffer == 0) /* If there is nothing in
the buffer then wait */
pthread_cond_wait(&condc, &the_mutex);
buffer = 0;
pthread_cond_signal(&condp); /* wake up consumer */
pthread_mutex_unlock(&the_mutex); /* release the buffer */
}
pthread_exit(0);
}
int main(int argc, char **argv) {
pthread_t pro, con;
// Initialize the mutex and condition variables
/* What's the NULL for ??? */
pthread_mutex_init(&the_mutex, NULL);
pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */
pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */
// Create the threads
pthread_create(&con, NULL, consumer, NULL);
pthread_create(&pro, NULL, producer, NULL);
// Wait for the threads to finish
// Otherwise main might run to the end
// and kill the entire process when it exits.
pthread_join(&con, NULL);
pthread_join(&pro, NULL);
// Cleanup -- would happen automatically at end of program
pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */
pthread_cond_destroy(&condc); /* Free up consumer condition variable */
pthread_cond_destroy(&condp); /* Free up producer condition variable */
}
Comments
Post a Comment