0% found this document useful (0 votes)
40 views2 pages

Lab 6 Step 2

Uploaded by

api-694081510
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views2 pages

Lab 6 Step 2

Uploaded by

api-694081510
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 2

// Name: Benjamin Shafer

// Date: 2023-08-01
// Title: Lab6 - Step 2
// Description: : This program recreates the producer-consumer problem where
// the alphabet is produced and consumed. It creates 2 threads, 1 for the producer
// and 1 for the consumer. It uses 3 semaphores to synchronize a buffer that is
// shared by the producer and consumer threads. One semaphore is used control
// filling the buffer, one is used to control emptying the buffer, and one is used
// as a mutex lock for the buffer. The threads will print out what character is
being
// produced or consumed. Once threads are finished with the alphabet, the main
thread exits.

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
#include <semaphore.h>

//Shared data: semaphore full, empty, mutex;


//pool of n buffers, each can hold one item
//mutex provides mutual exclusion to the buffer pool
//empty and full count the number of empty and full buffers
//Initially: full = 0, empty = MAX_BUFFER, mutex = 1

#define MAX_BUFFER 5 // Size of the buffer


sem_t mutex; // Semaphore used as a mutex lock for the buffer's critical sections
sem_t empty; // Semaphore used to track the empty spots in the buffer
sem_t full; // Semaphore used to track the full spots in the buffer

int buffer[MAX_BUFFER]; // Buffer data shared between threads


int next_in = 0; // Index to insert data into buffer
int next_out = 0; // Index to pull data from buffer

char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // Alphabet to produce/consume

// Producer method to add values to the buffer.


void put(char value) {
buffer[next_in] = value;
next_in = (next_in + 1) % MAX_BUFFER;
printf("Producer: %c\n", value);
}

// Consumer method to pull values from the buffer.


char get() {
char tmp = buffer[next_out];
next_out = (next_out + 1) % MAX_BUFFER;
printf("Consumer: %c\n", tmp);
return tmp;
}

// Method used to start a producer thread.


void *produce(void *arg) {
int i;
for (int i = 0; i < sizeof(alphabet) - 1; i++) {
sem_wait(&empty); // Wait for empty buffer
sem_wait(&mutex); // Wait for critical section
put(alphabet[i]);
sem_post(&mutex); // Release the critical section
sem_post(&full); // Signal the buffer is full.
}
}

// Method used to start a consumer thread.


void *consume(void *arg) {
int i;
for (i=0; i < sizeof(alphabet) - 1; i++) {
sem_wait(&full); // Wait for full buffer
sem_wait(&mutex); // Wait for critical section
int tmp = get();
sem_post(&mutex); // Release the critical section
sem_post(&empty); // Signal the buffer is empty.
}
}

int main(int argc, char *argv[]) {

// Initialize each semaphore and verify success.


int rc;
rc = sem_init(&empty, 0, MAX_BUFFER); // Initialize the empty semaphore with
MAX_BUFFERS
assert(rc == 0);
rc = sem_init(&full, 0, 0); // Initialize the full semaphore with 0
assert(rc == 0);
rc = sem_init(&mutex, 0, 1); // Initialize the mutex semaphore with 1
assert(rc == 0);

// Create and Start the producer/consumer threads.


pthread_t producer, consumer;
pthread_create(&producer, NULL, produce, NULL);
pthread_create(&consumer, NULL, consume, NULL);

// Have the main thread wait for the producer/consumer threads to finish.
pthread_join(producer, NULL);
pthread_join(consumer, NULL);

printf("Main thread done.\n");

// Destroy the semaphores


sem_destroy(&mutex);
sem_destroy(&empty);
sem_destroy(&full);

return 0;
}

You might also like