ArchiSys/TD/TD8/exercise1b.c
2024-04-19 08:11:16 +02:00

121 lines
2.8 KiB
C

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#define N 10
#define PROD 5
#define CONS 3
#define PROD_MAX 500
#define DELAY 1
#define RED "\033[31m"
#define RESET "\033[0m"
sem_t sem_prod;
sem_t sem_cons;
sem_t sem_renderer;
int shared_buffer[N];
pthread_mutex_t lock;
void* producteur(void* args) {
while (1) {
sem_wait(&sem_prod);
pthread_mutex_lock(&lock);
int i = -1;
while (++i < N) {
if (shared_buffer[i] == -1) {
shared_buffer[i] = rand()%PROD_MAX;
sem_post(&sem_cons);
sem_post(&sem_renderer);
//printf("placed@%d !\n", i);
break;
}
}
if (i >= N) {
fprintf(stderr, "Can't place my product !\n");
exit(1);
}
pthread_mutex_unlock(&lock);
sleep(DELAY);
}
return NULL;
}
void* consommateur(void* args) {
while (1) {
sem_wait(&sem_cons);
pthread_mutex_lock(&lock);
int i = -1;
while (++i < N) {
if (shared_buffer[i] != -1) {
shared_buffer[i] = -1;
//printf("got@%d !\n", i);
sem_post(&sem_prod);
sem_post(&sem_renderer);
break;
}
}
if (i >= N) {
fprintf(stderr, "Can't get a product !\n");
exit(1);
}
pthread_mutex_unlock(&lock);
sleep(DELAY);
}
return NULL;
}
void* renderer(void* args) {
while (1) {
sem_wait(&sem_renderer);
pthread_mutex_lock(&lock);
printf("\r");
for (int i=0; i < N; i++) {
if (shared_buffer[i] == -1) {
printf(RED "%3d " RESET, shared_buffer[i]);
} else {
printf("%3d ", shared_buffer[i]);
}
}
pthread_mutex_unlock(&lock);
}
}
int main() {
for (int i=0; i < N; i++) {
shared_buffer[i] = -1;
}
pthread_mutex_init(&lock, NULL);
pthread_t tid[PROD+CONS+1];
sem_init(&sem_prod, 0, N);
sem_init(&sem_cons, 0, 0);
sem_init(&sem_renderer, 0, 1);
for (int i=0; i < PROD; i++) {
pthread_create(&(tid[i]), NULL, &producteur, NULL);
}
for (int i=0; i < CONS; i++) {
pthread_create(&(tid[i+PROD]), NULL, &consommateur, NULL);
}
// Additional renderer thread to display the state of the market
pthread_create(&(tid[CONS+PROD]), NULL, &renderer, NULL);
for (int i=0; i < PROD+CONS+1; i++) {
pthread_join(tid[i], NULL);
}
sem_destroy(&sem_cons);
sem_destroy(&sem_prod);
return 0;
}