/* prod_cons_sem.
c
* Producteur-consommateur avec buffer de 5 cases (sémaphores POSIX).
*/
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h> /* usleep */
#define TAILLE_BUF 5
#define NB_ITEMS 10
int buffer[TAILLE_BUF];
int head = 0, tail = 0; /* indices circulaires */
sem_t vide; /* compte les cases libres (initialement 5) */
sem_t plein; /* compte les cases occupées (initialement 0) */
sem_t mutex; /* protège l’accès au buffer */
void *producteur(void *arg)
{
for (int n = 1; n <= NB_ITEMS; ++n) {
sem_wait(&vide); /* attendre une place libre */
sem_wait(&mutex); /* ---- entrée section critique ---- */
buffer[tail] = n;
tail = (tail + 1) % TAILLE_BUF;
printf("[Prod] produit %d\n", n);
sem_post(&mutex); /* ---- sortie section critique ---- */
sem_post(&plein); /* signaler un nouvel élément */
usleep(80 * 1000); /* mini délai pour la démo */
}
return NULL;
}
void *consommateur(void *arg)
{
for (int i = 0; i < NB_ITEMS; ++i) {
sem_wait(&plein); /* attendre un élément dispo */
sem_wait(&mutex); /* ---- entrée section critique ---- */
int x = buffer[head];
head = (head + 1) % TAILLE_BUF;
printf(" [Cons] consomme %d\n", x);
sem_post(&mutex); /* ---- sortie section critique ---- */
sem_post(&vide); /* libérer une case */
usleep(120 * 1000); /* mini délai pour la démo */
}
return NULL;
}
int main(void)
{
pthread_t prod, cons;
/* Initialisation des sémaphores */
sem_init(&vide, 0, TAILLE_BUF); /* 5 places libres */
sem_init(&plein, 0, 0); /* 0 éléments à consommer */
sem_init(&mutex, 0, 1); /* verrou binaire */
pthread_create(&prod, NULL, producteur, NULL);
pthread_create(&cons, NULL, consommateur, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
sem_destroy(&vide);
sem_destroy(&plein);
sem_destroy(&mutex);
puts("\nTous les éléments ont été produits et consommés.");
return 0;
}