/** * Starting point code from: * @author Gagne, Galvin, Silberschatz * Operating System Concepts - Seventh Edition * Copyright John Wiley & Sons - 2005. * Implements pthread based producer/consumer solution using semaphores. * */ /* Modified by Krishna Sivalingam - Feb. 2006 */ #include #include #include #include #define BUFFER_SIZE 10 typedef struct { int pc_buffer[BUFFER_SIZE]; int in; int out; } my_buffer; my_buffer Buffer1; /* Data Shared by threads. */ sem_t full, empty, mutex; void *producer(); /* the thread */ void *consumer(); /* the thread */ int main(int argc, char *argv[]) { pthread_t tid1, tid2; /* the thread identifier */ pthread_attr_t attr; /* set of attributes for the thread */ sem_init(&full, 0, 0); sem_init(&empty, 0, BUFFER_SIZE); sem_init(&mutex, 0, 1); /* get the default attributes */ pthread_attr_init(&attr); /* create the threads */ pthread_create(&tid1,&attr,producer, NULL); pthread_create(&tid2,&attr,consumer, NULL); /* now wait for threads to exit */ pthread_join(tid1,NULL); pthread_join(tid2,NULL); } /** * Producer thread */ void *producer(void *param) { int i, err; srandom(10000); /* Initialize random seed. */ for (i = 0; i < 20; i++) { sleep(random() % 2); /* Sleep for random time. */ sem_wait(&empty); sem_wait(&mutex); /* Add item to buffer */ Buffer1.pc_buffer[Buffer1.in] = (int) random() % 1000; fprintf(stdout," Item %d produced: %d\n", i, Buffer1.pc_buffer[Buffer1.in]); /* Update in pointer. */ Buffer1.in = (Buffer1.in + 1) % BUFFER_SIZE; sem_post(&mutex); sem_post(&full); } /* End for; produces 20 items */ pthread_exit(0); } /** * Consumer thread */ void *consumer(void *param) { int i, err; for (i = 0; i < 20; i++) { sem_wait(&full); sem_wait(&mutex); fprintf(stdout," \t\t\tItem %d consumed: %d\n", i, Buffer1.pc_buffer[Buffer1.out]); /* Update out pointer. */ Buffer1.out = (Buffer1.out + 1) % BUFFER_SIZE; sleep(random() % 2); /* Sleep for random time. */ sem_post(&mutex); sem_post(&empty); } /* End for; consumes 20 items */ pthread_exit(0); }