/** * 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(void *param); /* the thread */ void *consumer(void *param); /* the thread */ int main(int argc, char *argv[]) { pthread_t tid1, tid2, tid3, tid4; /* 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); srandom(10000); /* Initialize random seed. */ /* get the default attributes */ pthread_attr_init(&attr); /* create the threads */ pthread_create(&tid1,&attr,producer, "1"); pthread_create(&tid2,&attr,producer, "2"); pthread_create(&tid3,&attr,consumer, "1"); pthread_create(&tid4,&attr,consumer, "2"); /* now wait for threads to exit */ pthread_join(tid1,NULL); pthread_join(tid2,NULL); pthread_join(tid3,NULL); pthread_join(tid4,NULL); } /** * Producer thread */ void *producer(void *param) { int i, err, myid; myid = atoi((char *)param); i = 0; while (1) { 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,"Producer %d, Item %d produced: %d\n", myid, i, Buffer1.pc_buffer[Buffer1.in]); i++; /* 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, myid; myid = atoi((char *)param); for (i = 0; i < 40; i++) { sem_wait(&full); sem_wait(&mutex); fprintf(stdout," \t\t\t Cons: %d Item %d consumed: %d\n", myid,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); }