Created
March 13, 2013 07:38
-
-
Save banderson623/5150021 to your computer and use it in GitHub Desktop.
This is part 1 with some extra consumers. Runs on OS X too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. (70pts) Develop a monitor in C (using pthread library functions) or Java to solve the producer-consumer problem. [Hint: your program can be cased on the pseudo-code on Page 7 of 2013-3-4's lecture] | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <semaphore.h> | |
#define CAN_CONSUME_PATH "/tmp/canConsume" | |
#define CAN_PRODUCE_PATH "/tmp/canProduce" | |
sem_t* canConsume; | |
sem_t* canProduce; | |
int consumerThreadId = 1; | |
//here we define our threads 0 and 1 | |
pthread_t tids[5]; | |
int itemsInBuffer = 0; | |
// This is our buffer, it can be any size | |
#define BUFFER_SIZE 5 | |
int buffer[BUFFER_SIZE]; | |
void* consumerThreadFunction(void* x){ | |
int id = consumerThreadId++; | |
printf("Consumer %d: [thread starts]\n",id); | |
while(1){ | |
// wait until we've been cleared to consume | |
printf("Consumer %d: [check]\n",id); | |
sem_wait(canConsume); | |
if(itemsInBuffer > 0){ | |
printf("Consumer %d: [Consuming] itemsInBuffer: %d\n",id,itemsInBuffer); | |
//consume something, by changing the buffer | |
// value from a 1 to a 0. I guess we consume 1's | |
// buffer[itemsInBuffer-1] = 0; | |
// reduce the count of the items in the buffer | |
itemsInBuffer--; | |
printf("Consumer %d: [done] itemsInBuffer: %d\n",id,itemsInBuffer); | |
sem_post(canProduce); | |
} | |
printf("Consumer %d: [sleeping]\n",id); | |
} | |
return 0; | |
} | |
void* producerThreadFunction(void* x) | |
{ | |
printf("Producer thread starts.\n"); | |
while(1){ | |
int sleepTime =rand() % 1000; | |
printf("Producer: [sleep %d]\n",sleepTime); | |
usleep(sleepTime*1000); | |
printf("Producer: [check]\n"); | |
sem_wait(canProduce); | |
while(itemsInBuffer < (BUFFER_SIZE)){ | |
printf("Producer: [Producing] itemsInBuffer: %d\n",itemsInBuffer); | |
// reduce the count of the items in the buffer | |
itemsInBuffer++; | |
printf("Producer: [Done] itemsInBuffer: %d\n",itemsInBuffer); | |
sem_post(canConsume); | |
} | |
} | |
return 0; | |
} | |
//Initializes the semaphores, returns 0 on success | |
int initializeSemaphores(); | |
// closes and unlinks the semaphores | |
void cleanupSemaphores(); | |
int main() { | |
// sem_init() returns 0 on success; on error, -1 is returned... | |
cleanupSemaphores(); | |
if(initializeSemaphores() == 0){ | |
printf("Creating threads...\n"); | |
pthread_create(tids, NULL, producerThreadFunction, NULL); | |
pthread_create(tids+1,NULL, consumerThreadFunction,NULL); | |
pthread_create(tids+2,NULL, consumerThreadFunction,NULL); | |
pthread_create(tids+3,NULL, consumerThreadFunction,NULL); | |
pthread_create(tids+4,NULL, consumerThreadFunction,NULL); | |
// pthread_create(tids+2,NULL,th2,NULL); | |
pthread_join(tids[0], NULL); | |
pthread_join(tids[1], NULL); | |
pthread_join(tids[2], NULL); | |
pthread_join(tids[3], NULL); | |
pthread_join(tids[4], NULL); | |
// clean up after ourselves | |
cleanupSemaphores(); | |
// use useful return value | |
return 0; | |
} else { | |
// explain we have a problem initializing, if I was serious I would use errno. | |
printf("Unable to initialize the semaphore\n"); | |
//useful return value | |
return -1; | |
} | |
} | |
int initializeSemaphores(){ | |
int returnValue = 1; | |
// I develop on Mac OS X and there are no nameless semaphores | |
// so I am stuck using named semaphores | |
if ((canConsume = sem_open(CAN_CONSUME_PATH, O_CREAT, 0644, 1)) == SEM_FAILED ) { | |
perror("sem_open"); | |
} else { | |
if ((canProduce = sem_open(CAN_PRODUCE_PATH, O_CREAT, 0644, 1)) == SEM_FAILED ) { | |
perror("sem_open"); | |
} else { | |
returnValue = 0; | |
} | |
} | |
return returnValue; | |
} | |
void cleanupSemaphores(){ | |
sem_close(canConsume); | |
sem_unlink(CAN_CONSUME_PATH); | |
sem_close(canProduce); | |
sem_unlink(CAN_PRODUCE_PATH); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment