0% found this document useful (0 votes)
4 views

Lab4_OS

The document contains code for three different implementations of the producer-consumer problem using threads, semaphores, and mutexes in C. Each implementation defines a buffer, producer, and consumer functions, managing synchronization to ensure proper access to the shared buffer. The code demonstrates the creation of threads, handling of semaphores, and cleanup of resources after execution.

Uploaded by

Khang Le
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Lab4_OS

The document contains code for three different implementations of the producer-consumer problem using threads, semaphores, and mutexes in C. Each implementation defines a buffer, producer, and consumer functions, managing synchronization to ensure proper access to the shared buffer. The code demonstrates the creation of threads, handling of semaphores, and cleanup of resources after execution.

Uploaded by

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

Name: Lê Công Thái Khang

Student ID: ITITIU20224


OPERATING SYSTEM
Lab 4
I51:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define BUFFER_SIZE 5
#define PRODUCE_COUNT 20

int buffer[BUFFER_SIZE];
int in = 0, out = 0;

sem_t empty; // counts empty slots


sem_t full; // counts full slots
pthread_mutex_t mutex; // protects buffer

void* producer(void* arg) {


for (int i = 0; i < PRODUCE_COUNT; ++i) {
int item = rand() % 100;

sem_wait(&empty); // wait for empty slot


pthread_mutex_lock(&mutex);

buffer[in] = item;
printf("Producer produced: %d at index %d\n", item, in);
in = (in + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&full); // increase count of full slots

usleep(100000); // simulate delay


}
return NULL;
}
void* consumer(void* arg) {
int id = *((int*)arg);
for (int i = 0; i < PRODUCE_COUNT / 2; ++i) {
sem_wait(&full); // wait for full slot
pthread_mutex_lock(&mutex);

int item = buffer[out];


printf("Consumer %d consumed: %d at index %d\n", id, item, out);
out = (out + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&empty); // increase count of empty slots

usleep(150000); // simulate delay


}
return NULL;
}

int main() {
pthread_t prod, cons1, cons2;
int id1 = 1, id2 = 2;

// Initialize semaphore and mutex


sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);

// Create threads
if (pthread_create(&prod, NULL, producer, NULL) != 0) {
perror("Failed to create producer thread");
exit(EXIT_FAILURE);
}
if (pthread_create(&cons1, NULL, consumer, &id1) != 0) {
perror("Failed to create consumer 1 thread");
exit(EXIT_FAILURE);
}
if (pthread_create(&cons2, NULL, consumer, &id2) != 0) {
perror("Failed to create consumer 2 thread");
exit(EXIT_FAILURE);
}

// Wait for threads


pthread_join(prod, NULL);
pthread_join(cons1, NULL);
pthread_join(cons2, NULL);

// Destroy semaphore and mutex


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

return 0;
}

I52:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define BUFFER_SIZE 5
#define PRODUCE_COUNT 10

int buffer[BUFFER_SIZE];
int in = 0, out = 0;

sem_t empty; // Semaphore for empty slots


sem_t full; // Semaphore for filled slots
pthread_mutex_t mutex; // Mutex for buffer access

void* producer(void* arg) {


int id = *((int*)arg);
for (int i = 0; i < PRODUCE_COUNT; ++i) {
int item = rand() % 100;

if (sem_wait(&empty) != 0) {
perror("sem_wait failed in producer");
pthread_exit(NULL);
}

if (pthread_mutex_lock(&mutex) != 0) {
perror("mutex lock failed in producer");
pthread_exit(NULL);
}
buffer[in] = item;
printf("Producer %d produced: %d at index %d\n", id, item, in);
in = (in + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&full);

usleep(100000); // simulate some delay


}

pthread_exit(NULL);
}

void* consumer(void* arg) {


for (int i = 0; i < PRODUCE_COUNT * 2; ++i) {
if (sem_wait(&full) != 0) {
perror("sem_wait failed in consumer");
pthread_exit(NULL);
}

if (pthread_mutex_lock(&mutex) != 0) {
perror("mutex lock failed in consumer");
pthread_exit(NULL);
}

int item = buffer[out];


printf("Consumer consumed: %d at index %d\n", item, out);
out = (out + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&empty);

usleep(150000); // simulate some delay


}

pthread_exit(NULL);
}

int main() {
pthread_t prod1, prod2, cons;
int id1 = 1, id2 = 2;

// Initialize semaphores and mutex


if (sem_init(&empty, 0, BUFFER_SIZE) != 0 ||
sem_init(&full, 0, 0) != 0 ||
pthread_mutex_init(&mutex, NULL) != 0) {
perror("Initialization failed");
exit(EXIT_FAILURE);
}

// Create threads
if (pthread_create(&prod1, NULL, producer, &id1) != 0 ||
pthread_create(&prod2, NULL, producer, &id2) != 0 ||
pthread_create(&cons, NULL, consumer, NULL) != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}

// Wait for threads to complete


pthread_join(prod1, NULL);
pthread_join(prod2, NULL);
pthread_join(cons, NULL);

// Cleanup
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);

return 0;
}

I53:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define BUFFER_SIZE 5
#define PRODUCE_COUNT 10

int buffer[BUFFER_SIZE];
int in = 0, out = 0;

sem_t empty; // counts empty slots


sem_t full; // counts filled slots
pthread_mutex_t mutex; // mutex for buffer access

void* producer(void* arg) {


int id = *((int*)arg);
for (int i = 0; i < PRODUCE_COUNT; ++i) {
int item = rand() % 100;

if (sem_wait(&empty) != 0) {
perror("sem_wait failed in producer");
pthread_exit(NULL);
}

if (pthread_mutex_lock(&mutex) != 0) {
perror("mutex lock failed in producer");
pthread_exit(NULL);
}

buffer[in] = item;
printf("Producer %d produced: %d at index %d\n", id, item, in);
in = (in + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&full);

usleep(100000);
}

pthread_exit(NULL);
}

void* consumer(void* arg) {


int id = *((int*)arg);
for (int i = 0; i < PRODUCE_COUNT; ++i) {
if (sem_wait(&full) != 0) {
perror("sem_wait failed in consumer");
pthread_exit(NULL);
}

if (pthread_mutex_lock(&mutex) != 0) {
perror("mutex lock failed in consumer");
pthread_exit(NULL);
}

int item = buffer[out];


printf("Consumer %d consumed: %d at index %d\n", id, item, out);
out = (out + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);
sem_post(&empty);

usleep(150000);
}

pthread_exit(NULL);
}

int main() {
pthread_t prod1, prod2, cons1, cons2;
int id1 = 1, id2 = 2;

if (sem_init(&empty, 0, BUFFER_SIZE) != 0 ||
sem_init(&full, 0, 0) != 0 ||
pthread_mutex_init(&mutex, NULL) != 0) {
perror("Initialization failed");
exit(EXIT_FAILURE);
}

// Create threads
if (pthread_create(&prod1, NULL, producer, &id1) != 0 ||
pthread_create(&prod2, NULL, producer, &id2) != 0 ||
pthread_create(&cons1, NULL, consumer, &id1) != 0 ||
pthread_create(&cons2, NULL, consumer, &id2) != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}

// Join threads
pthread_join(prod1, NULL);
pthread_join(prod2, NULL);
pthread_join(cons1, NULL);
pthread_join(cons2, NULL);

// Cleanup
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);

return 0;
}

You might also like