vuoi
o PayPal
tutte le volte che vuoi
/*In un bar-pasticceria il barista prepara caffè e cornetti riempiendo i vassoi relativi SOLO
QUANDO SONO VUOTI, rispettivamente con 4 caffè e 6 cornetti. Quando ha riempito il vassoio
vuoto, il barista si blocca. Ogni cliente acquista un caffè e due cornetti. Se non trova il caffè e/o i
cornetti, il cliente sblocca il barista e poi si blocca in coda in attesa che questo riempia il vassoio
che si è vuotato.
Scrivere il thread barista e i thread cliente che richiamano rispettivamente le procedure
riempiVassoio() e faiColazione().*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_MAX_CAFFE 8
#define NUM_MAX_CORNETTI 12
#define CONSUMO_CORNETTI 2
#define CONSUMO_CAFFE 1
#define NUM_THREAD_CLIENTI 5
#define NUM_COLAZIONI 10
typedef struct{
int numCornetti;
int numCaffe;
}Vassoio;
Vassoio vassoio;
sem_t mutexVassoio;
sem_t mutexClientiAttivi;
sem_t mutexClientiInCoda;
sem_t mutexBaristaAttivo;
sem_t clienti;
sem_t barista;
int clientiAttivi = NUM_THREAD_CLIENTI;
int nClientiInCoda = 0;
int baristaAttivo = 1;
pthread_t tid[NUM_THREAD_CLIENTI + 1]; //array dei thread in esecuzione (uno per il barista e
gli altri sono clienti)
void faiColazione(int numCliente){
while(vassoio.numCaffe < CONSUMO_CAFFE || vassoio.numCornetti <
CONSUMO_CORNETTI){
//se il barista non è ancora stato svegliato lo sveglio io, altrimenti vado avanti
sem_wait(&mutexBaristaAttivo);
if(baristaAttivo == 0){
sem_post(&barista);
baristaAttivo=1;
}
sem_post(&mutexBaristaAttivo);
//mi metto in attesa sulla coda clienti
sem_wait(&mutexClientiInCoda);
nClientiInCoda++;
printf("Cliente %d in attesa...\n",numCliente);
sem_post(&mutexClientiInCoda);
sem_post(&mutexVassoio);
sem_wait(&clienti);
sem_wait(&mutexVassoio);
printf("Cliente %d sbloccato!\n",numCliente);
}
vassoio.numCaffe -= CONSUMO_CAFFE;
vassoio.numCornetti -= CONSUMO_CORNETTI;
printf("Cliente %d consuma -- Rimasti--> Cornetti: %d | Caffe':
%d\n",numCliente,vassoio.numCornetti,vassoio.numCaffe);
}
void riempiVassoio(){
if(vassoio.numCaffe==0){
printf("Barista riempe vassoio di caffe'\n");
vassoio.numCaffe += NUM_MAX_CAFFE;
}
if(vassoio.numCornetti == 0){
printf("Barista riempe vassoio di cornetti\n");
vassoio.numCornetti += NUM_MAX_CORNETTI;
}
}
int ciSonoClientiAttivi(int clientiAttivi){
if(clientiAttivi==0){
sem_post(&mutexClientiAttivi);
sem_post(&mutexVassoio);
printf("Barista chiude...\n");
pthread_exit(NULL);
}
return 1;
}
void* threadCliente(void* args){
int numCliente = (int)(args) , n = NUM_COLAZIONI;
printf("Creato cliente %d\n",numCliente);
while(n>0){
sem_wait(&mutexVassoio);
faiColazione(numCliente);
sem_post(&mutexVassoio);
n--;
}
sem_wait(&mutexClientiAttivi);
printf("Cliente %d se ne va...\n",numCliente);
clientiAttivi--;
if(clientiAttivi==0){
//se sono l'ultimo cliente ad andarmene, sveglio il barista perchè chiuda
sem_post(&barista);
}
sem_post(&mutexClientiAttivi);
pthread_exit(NULL);
}
void* threadBarista(void* args){
printf("Creato barista\n");
while(1){
sem_wait(&mutexVassoio);
sem_wait(&mutexClientiAttivi);
while(vassoio.numCaffe != 0 && vassoio.numCornetti != 0 &&
ciSonoClientiAttivi(clientiAttivi)){
sem_post(&mutexClientiAttivi);
sem_wait(&mutexBaristaAttivo);
baristaAttivo=0;
sem_post(&mutexBaristaAttivo);
printf("Barista in attesa...\n");
sem_post(&mutexVassoio);
sem_wait(&barista);
sem_wait(&mutexVassoio);
printf("\nBarista svegliato!\n");
sem_wait(&mutexClientiAttivi);
}
sem_post(&mutexClientiAttivi);
riempiVassoio();
printf("Barista sblocca i clienti in coda!\n");
int i;
//sblocco tutti i clienti in coda
sem_wait(&mutexClientiInCoda);
for(i=0;i<nClientiInCoda;i++){
sem_post(&clienti);