Sep 05, 2024 Semaphores
I wish I knew what they are and what they do. Producer-Consumer Problem
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
void* producer(void* arg) {
int item;
while (1) {
item = rand() % 100;
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = item;
printf("Producer produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&full);
sleep(1);
}
}
void* consumer(void* arg) {
int item;
while (1) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
item = buffer[out];
printf("Consumer consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
sleep(1);
}
}
int main() {
pthread_t prod, cons;
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);
return 0;
}
Producer produced: 41
Consumer consumed: 41
Producer produced: 67
Consumer consumed: 67
Producer produced: 34
Consumer consumed: 34
Producer produced: 0
Consumer consumed: 0
Producer produced: 69
Consumer consumed: 69
Producer produced: 24
Consumer consumed: 24
Readers-Writers Problem
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
int read_count = 0;
sem_t mutex;
sem_t write_lock;
void* reader(void* arg) {
int num = *(int*)arg;
while (1) {
sem_wait(&mutex);
read_count++;
if (read_count == 1) {
sem_wait(&write_lock);
}
sem_post(&mutex);
printf("Reader %d is reading\n", num);
sleep(1);
sem_wait(&mutex);
read_count--;
if (read_count == 0) {
sem_post(&write_lock);
}
sem_post(&mutex);
sleep(1);
}
}
void* writer(void* arg) {
int num = *(int*)arg;
while (1) {
sem_wait(&write_lock);
printf("Writer %d is writing\n", num);
sleep(1);
sem_post(&write_lock);
sleep(1);
}
}
int main() {
pthread_t r1, r2, w1, w2;
int r_id1 = 1, r_id2 = 2, w_id1 = 1, w_id2 = 2;
sem_init(&mutex, 0, 1);
sem_init(&write_lock, 0, 1);
pthread_create(&r1, NULL, reader, &r_id1);
pthread_create(&r2, NULL, reader, &r_id2);
pthread_create(&w1, NULL, writer, &w_id1);
pthread_create(&w2, NULL, writer, &w_id2);
pthread_join(r1, NULL);
pthread_join(r2, NULL);
pthread_join(w1, NULL);
pthread_join(w2, NULL);
sem_destroy(&mutex);
sem_destroy(&write_lock);
return 0;
}
Reader 1 is reading
Reader 2 is reading
Writer 1 is writing
Writer 2 is writing
Reader 1 is reading
Reader 2 is reading
Writer 1 is writing
Writer 2 is writing
Reader 2 is reading
Reader 1 is reading
Dining Philosophers’ Problem
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define N 5
sem_t chopsticks[N];
void* philosopher(void* num) {
int id = *(int*)num;
while (1) {
printf("Philosopher %d is thinking\n", id);
sleep(1);
printf("Philosopher %d is hungry\n", id);
sem_wait(&chopsticks[id]);
sem_wait(&chopsticks[(id + 1) % N]);
printf("Philosopher %d is eating\n", id);
sleep(2);
sem_post(&chopsticks[id]);
sem_post(&chopsticks[(id + 1) % N]);
printf("Philosopher %d is done eating\n", id);
sleep(1);
}
}
int main() {
pthread_t philosophers[N];
int philosopher_ids[N];
for (int i = 0; i < N; i++) {
sem_init(&chopsticks[i], 0, 1);
}
for (int i = 0; i < N; i++) {
philosopher_ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_ids[i]);
}
for (int i = 0; i < N; i++) {
pthread_join(philosophers[i], NULL);
}
for (int i = 0; i < N; i++) {
sem_destroy(&chopsticks[i]);
}
return 0;
}
Philosopher 0 is thinking
Philosopher 1 is thinking
Philosopher 2 is thinking
Philosopher 2 is hungry
Philosopher 1 is hungry
Philosopher 0 is hungry
Philosopher 2 is eating
Philosopher 1 is eating
Philosopher 2 is done eating
Philosopher 2 is thinking
Philosopher 0 is eating