3) Prende l'ordinazione che consiste in tre interi dati in maniera random (rispettivamente il numero di panini, di porzioni di patatine e di bibite)
sem_patate, /* Semaforo per i due distributori di patatine */
mut_bibite; /* Mutex per il distributore di bibite */
fprintf(stderr,"Errore rilascio semaforo panini %d\n");
Omissioni:
3) Prende l'ordinazione che consiste in tre interi dati in maniera random (rispettivamente il numero di panini, di porzioni di patatine e di bibite
sem_patate, /* Semaforo per i due distributori di patatine */
mut_bibite; /* Mutex per il distributore di bibite */
fprintf(stderr,"Errore rilascio mutex panini %d\n");
La versione più vecchia di questa pagina è stata modificata il 2007-06-12 19:05:57 da GaS []
Vista della pagina:
Fast Food (18/06/2007)
Si simuli un Fast Food con tre casse e tre cassieri/camerieri e tre possibili tipologie di cibo:
Mentre i panini sono distribuiti in tre distributori (uno per cassa), le porzioni di patatine sono contenute in due distributori e le bibite in un unico frigo.
Questo comporta che i cassieri che devono soddisfare un'ordinazione con patatine o bibite devono assicurarsi la disponibilità di uno dei distributori di patatine e del frigo.
La vita del cassiere è:
- Finchè non è ora di chiusura:
- Arriva un cliente
- Prende l'ordinazione che consiste in tre interi dati in maniera random (rispettivamente il numero di panini, di porzioni di patatine e di bibite
- Il cassiere registra l'ordinazione e la soddisfa
- Torna al punto 2
Al termine si devono stampare, per ogni cassa, il numero di panini, porzioni di patatine e bibite vendute.
Sviluppare in linguaggio C un programma che simuli con i thread la situazione descritta, commentando le scelte fatte.
/*
*
* Per la risoluzione del problema ho creato 1 thread che aspetta un input
* da tastiera per "chiudere il fast food" e 3 threads cameriere che ricevono
* di volta in volta un ordine (che si può identificare con il cliente) e lo
* eseguono.
* Le risorse a disposizione sono i 3 distributori di panini (semaforo), 2
* distributori di patatine (semaforo) e un distributore di bibite (mutex).
*
* La scelta di un semaforo per i panini è stata fatta in quanto l'arrivo di
* un eventuale altro cameriere/cassiere ne renderebbe necessario
* l'utilizzo, ma è contestabile.
*/
/****************************************************************************/
/* LIBRERIE */
/****************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
/****************************************************************************/
/* MACRO */
/****************************************************************************/
#define GetRandom(min, max) ((rand() % (int)(((max) + 1) - (min))) + (min))
/****************************************************************************/
/* TIPI E STRUTTURE */
/****************************************************************************/
typedef struct s_cameriere{
unsigned int id; /* id del cameriere */
unsigned int n_panini; /* numero di panini serviti */
unsigned int n_patate; /* numero di porzioni di patatine servite */
unsigned int n_bibite; /* numero di bibite servite */
} t_cameriere;
typedef struct s_ordine{
unsigned int n_panini; /* numero di panini ordinati */
unsigned int n_patate; /* numero di porzioni di patatine ordinate */
unsigned int n_bibite; /* numero di bibite ordinate */
} t_ordine;
/****************************************************************************/
/* VARIABILI GLOBALI */
/****************************************************************************/
#define N 3 /* La costante N rappresenta il numero di camerieri */
#define PRENDI_ITEM 250 /* Tempo impiegato per prendere un tipo di oggetto */
HANDLE sem_panini, /* Semaforo per i distributori di panini */
sem_patate, /* Semaforo per i due distributori di patatine */
mut_bibite; /* Mutex per il distributore di bibite */
int continua = 1; /* variabile controllo chiusura Fast Food */
/****************************************************************************/
/* FORWARD DECLARATIONS */
/****************************************************************************/
DWORD lavora (t_cameriere *cam); /* funzione dei threads cameriere */
t_ordine *ordine(t_ordine *ord); /* creazione ordine */
DWORD si_chiude (int *continua); /* funzione del thread end */
/****************************************************************************/
/* MAIN */
/****************************************************************************/
main(){
unsigned int i;
t_cameriere cam[N];
HANDLE thr_end, /* thread che controlla la chiusura FF */
thr_cameriere[N]; /* threads cameriere */
/* inizializzazione seme */
srand( (unsigned int) time (NULL) );
/* inizializzazione camerieri */
for(i=0;i<N;i++){
cam[i].id = i;
cam[i].n_panini = 0;
cam[i].n_patate = 0;
cam[i].n_bibite = 0;
}
/* inizializzazione mutex panini */
if( (sem_panini = CreateSemaphore(NULL, 3, 3, NULL) ) == NULL)
fprintf(stderr,"Errore creazione semaforo panini %d\n");
/* inizializzazione semaforo patate */
if( (sem_patate = CreateSemaphore(NULL, 2, 2, NULL) ) == NULL)
fprintf(stderr,"Errore creazione semaforo patatine %d\n");
/* inizializzazione mutex bibite */
if( (mut_bibite = CreateMutex(NULL, FALSE, NULL) ) == NULL)
fprintf(stderr,"Errore creazione mutex bibite %d\n");
/* CREAZIONE THREAD CHIUSURA FAST FOOD */
if( (thr_end = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) si_chiude, &continua, 0, NULL) ) == NULL)
fprintf(stderr,"Errore creazione thread chiusura fast food %d\n");
/* INIZIALIZZAZIONE THREADS CAMERIERE */
for(i=0;i<N;i++)
if( (thr_cameriere[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) lavora, &cam[i], 0, NULL) ) == NULL)
fprintf(stderr,"Errore creazione thread cameriere %d\n");
/* TERMINAZIONE THREADS */
for(i=0;i<N;i++)
if(WaitForSingleObject(thr_cameriere[i], INFINITE) == WAIT_FAILED)
printf("Errore terminazione thread cameriere %d\n",i);
else
printf("Sono il cameriere %d, chiudo la cassa!\n",cam[i].id);
/* STAMPA STATISTICHE*/
printf("\n\n CHIUSURA FAST FOOD\n");
for(i=0;i<N;i++){
printf("\n Il cameriere %d ha servito:\n",cam[i].id);
printf("\t %d panini\n",cam[i].n_panini);
printf("\t %d porzioni di patatine \n",cam[i].n_patate);
printf("\t %d bibite\n",cam[i].n_bibite);
}
return 0;
}
/****************************************************************************/
/* CHIUSURA FAST FOOD */
/****************************************************************************/
DWORD si_chiude (int *continua)
{
getch();
*continua = 0;
return 0;
}
/****************************************************************************/
/* ORDINAZIONE */
/****************************************************************************/
t_ordine *ordine(t_ordine *ord)
{
ord = (t_ordine *) malloc (sizeof(t_ordine));
ord->n_panini = GetRandom(1,10);
ord->n_patate = GetRandom(1,10);
ord->n_bibite = GetRandom(1,10);
return ord;
}
/****************************************************************************/
/* THREAD CAMERIERE */
/****************************************************************************/
DWORD lavora (t_cameriere *cam)
{
printf("Sono il cameriere %d, mi metto al lavoro!\n",cam->id);
while(continua){
t_ordine *ord;
/* ordinazione */
ord = ordine(ord);
/* ======================================== evasione ordinazione == */
/* PANINI */
if( (WaitForSingleObject(sem_panini, INFINITE) ) == WAIT_FAILED)
fprintf(stderr,"Errore acquisizione semaforo panini %d\n");
/* sezione critica... prendo i panini */
Sleep(ord->n_panini*PRENDI_ITEM);
if( (ReleaseSemaphore(sem_panini, 1, NULL) ) == 0)
fprintf(stderr,"Errore rilascio mutex panini %d\n");
/* PATATINE */
if( (WaitForSingleObject(sem_patate, INFINITE) ) == WAIT_FAILED)
fprintf(stderr,"Errore acquisizione semaforo patate %d\n");
/* sezione critica... prendo le patatine */
Sleep(ord->n_patate*PRENDI_ITEM);
if( (ReleaseSemaphore(sem_patate, 1, NULL) ) == 0)
fprintf(stderr,"Errore rilascio semaforo patatine %d\n");
/* BIBITE */
if( (WaitForSingleObject(mut_bibite, INFINITE) ) == WAIT_FAILED)
fprintf(stderr,"Errore acquisizione mutex bibite %d\n");
/* sezione critica... prendo le bibite */
Sleep(ord->n_bibite*PRENDI_ITEM);
if( (ReleaseMutex(mut_bibite) ) == 0)
fprintf(stderr,"Errore rilascio mutex bibite %d\n");
/* ======================================== ordinazione evasa ===== */
printf("#%d C ha evaso l'ordinazione (%d panini, %d patatine, %d bibite)\n",cam->id,ord->n_panini,ord->n_patate,ord->n_bibite);
/* registra items presi */
cam->n_panini += ord->n_panini;
cam->n_patate += ord->n_patate;
cam->n_bibite += ord->n_bibite;
/* libero la memoria dell'ordinazione */
free(ord);
}
return 0;
}
Laboratorio di Sistemi Operativi