121 lines
2.8 KiB
C
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;
|
|
}
|