Skip to content

Instantly share code, notes, and snippets.

@albertzak
Created May 13, 2016 06:52
Show Gist options
  • Save albertzak/f697d848e3d2d0350426e9dc1c97b094 to your computer and use it in GitHub Desktop.
Save albertzak/f697d848e3d2d0350426e9dc1c97b094 to your computer and use it in GitHub Desktop.
boundedbuffer
/*****************************
* Fernlehre Bounded Buffer
* File: main.c
* Author: Granzer Wolfgang
* Version: 1.1
* Date: 05.05.2015
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include "boundedbuffer.h"
#define BUFFER_SIZE 3
#define THREAD_COUNT 24 // must be even
char buffer[BUFFER_SIZE];
pthread_t threads[THREAD_COUNT];
// forward declaration
void* threadProducer(void* param);
void* threadConsumer(void* param);
sem_t semBuffer, semAvailable, semFull;
int posProducer, posConsumer;
/**
* Main Program.
*/
int main(int argc, const char* argv[])
{
int i = 0;
int balance = 0;
int threshold = (THREAD_COUNT % 2) == 0 ? THREAD_COUNT : THREAD_COUNT -1;
/*
* Initialize the semaphores and indices.
*
*/
sem_init(&semBuffer, 0, 1);
sem_init(&semAvailable, 0, BUFFER_SIZE);
sem_init(&semFull, 0, 0);
printf("Fernlehre Bounded Buffer\n");
printf("----------------------------\n");
printf("Starting Threads ...\n");
// init random generator
srand(time(NULL));
for (i = 0; i < THREAD_COUNT; i++)
{
if (((balance * -1) < (threshold - i)) && ((balance >= (threshold - i) ) || (rand() % 2 == 0)))
{
pthread_create(&(threads[i]), NULL, &threadProducer, NULL);
balance--;
}
else
{
pthread_create(&(threads[i]), NULL, &threadConsumer, NULL);
balance++;
}
}
printf("Waiting for threads to terminate ...\n");
for (i = 0; i < THREAD_COUNT; i++)
{
pthread_join(threads[i], NULL);
}
printf("Finished! Bye ...\n");
return 0;
}
/**
* Thread Producer
*/
void* threadProducer(void* param)
{
char item = 0;
sem_wait(&semAvailable);
item = bb_produce();
sem_wait(&semBuffer);
buffer[++posProducer % BUFFER_SIZE] = item;
sem_post(&semBuffer);
sem_post(&semFull);
return 0;
}
/**
* Thread Consumer
*/
void* threadConsumer(void* param)
{
char item;
sem_wait(&semFull);
sem_wait(&semBuffer);
item = buffer[++posConsumer % BUFFER_SIZE];
sem_post(&semBuffer);
bb_consume(item);
sem_post(&semAvailable);
return 0;
}
@albertzak
Copy link
Author

Example Output:

Fernlehre Bounded Buffer
----------------------------
Starting Threads ...
Waiting for threads to terminate ...
Producing new item "G"
Consuming item "G"
Producing new item "I"
Consuming item "I"
Producing new item "V"
Consuming item "V"
Producing new item "J"
Consuming item "J"
Producing new item "P"
Consuming item "P"
Producing new item "L"
Consuming item "L"
Producing new item "S"
Consuming item "S"
Producing new item "J"
Consuming item "J"
Producing new item "R"
Consuming item "R"
Producing new item "J"
Consuming item "J"
Producing new item "V"
Consuming item "V"
Producing new item "S"
Consuming item "S"
Finished! Bye ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment