Skip to content

Instantly share code, notes, and snippets.

@banderson623
Created March 13, 2013 07:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save banderson623/5150021 to your computer and use it in GitHub Desktop.
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.
// 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