Ristorante (02/10/2006)
Si simuli un piccolo ristorante composto da 5 tavoli di 6 posti ciascuno.
I clienti arrivano al ristorante a gruppi di n da 1 a 6 con scadenza randomica da t a 4t e se disponibile si accomodano in uno dei tavoli viceversa aspettano il loro turno.
Quindi ordinato in un tempo nt e dopo una attesa di un tempo t1 consumano il pasto in un tempo random da t2 a 4t2.
Sviluppare in linguaggio C un programma che simuli con i thread la situazione descritta, commentando le scelte fatte.
//program ristorante
#include <stdio.h>
#include <windows.h>
#include <conio.h>
//funzione per la generazione di numeri random
#define GetRandom(min,max)((rand()%(int)(((max)+1)-(min)))+(min))
#define TAV 5
#define POSTI 6
#define T 1000
#define T1 3000
#define T2 2500
//prototipo di funzione per il thread finito
DWORD finito (LPDWORD lpdwParam);
//prototipo di funzione per il thread clienti
DWORD clienti(LPDWORD lpdwParam);
//vettore di semafori per i tavoli
HANDLE tavoli[TAV];
//variabile globale per la terminazione del programma
int fine=1;
//variabile globale che conta il numero di clienti che hanno pranzato al ristorante
int count=0;
//vettore dei posti che sono disponibili per ogni tavolo
int pfree[TAV]={POSTI,POSTI,POSTI,POSTI,POSTI};
//sezione critica per accedere al vettore dei posti disponibili
CRITICAL_SECTION cs;
/************************************************************************/
/* MAIN PROGRAMM */
/************************************************************************/
void main()
{
int i;
//id del gruppo di clienti che arrivano al ristorante
int id=0;
//handle per i thread finito e clienti
HANDLE hfinito, hclienti;
InitializeCriticalSection(&cs);
//inzio con la creazione dei semafori
for (i=0; i<TAV; i++)
if((tavoli[i]=CreateMutex(NULL,FALSE,NULL))==NULL)
fprintf(stderr,"Errore creazione mutex %d\n\n",i);
//creo prima il thread finito e poi i vari thread clienti
if ((hfinito=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)finito,(LPVOID)&fine,0,NULL))==NULL)
{
fprintf(stderr,"Errore creazione thread finito\n\n");
}
else
{
while (fine)
{
if ((hclienti=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)clienti,(LPVOID)id,0,NULL))==NULL)
{
fprintf(stderr,"Errore creazione thread clienti\n\n");
}
else
{
++id;
}
Sleep(T*(GetRandom(1,4)));
}
//termino correttamente i thread che sono ancora in esecuzione
TerminateThread(hclienti,0);
}
//stampo le statistiche
printf("Oggi hanno pranzato %d clienti\n\n\n",count);
}
/************************************************************************/
/* THREAD FINITO */
/************************************************************************/
DWORD finito(LPDWORD lpdwParam)
{
int *finish;
finish=(int*)lpdwParam;
getch();
*finish= 0;
return 0;
}
/************************************************************************/
/* THREAD CLIENTI */
/************************************************************************/
/*
Nota:
Suppongo che in ogni tavolo possano essere sistemati più gruppi (fino a 6 se ho gruppi da 1 cliente)
e che ogni gruppo aspetti un tavolo che abbia posti sufficienti per sedersi.
*/
DWORD clienti(LPDWORD lpdwParam)
{
//id del gruppo di clienti
int id;
id=(int)lpdwParam;
//booleano per vedere quando un gruppo trova posto
bool seduto=true;
DWORD table;
//numero di clienti nel gruppo
int nclienti=GetRandom(1,6);
printf("Gruppo %d: siamo in %d, aspettiamo un tavolo...\n\n",id,nclienti);
while (seduto)
{
//controlla un tavolo per vedere se ci sono abbastanza posti disponibili
table=WaitForMultipleObjects(TAV,tavoli,FALSE,INFINITE);
//Se ci sono abbastanza posti il gruppo si accomoda.
if (pfree[table]>=nclienti)
{
EnterCriticalSection(&cs);
pfree[table]-=nclienti;
printf("Gruppo %d: abbiamo trovato posto al tavolo %d\n\n",id,table+1);
seduto=FALSE;
ReleaseMutex(tavoli[table]);
LeaveCriticalSection(&cs);
}
//se non ci sono abbastanza posti allora il gruppo cerca un altro tavolo
else
{
ReleaseMutex(tavoli[table]);
}
}
printf("Gruppo %d: ordiniamo...\n\n",id);
Sleep(nclienti*T);
printf("Gruppo %d: abbiamo ordinato, aspettiamo l'ordine...\n\n",id);
Sleep(T1);
printf("Gruppo %d: stiamo mangiando...\n\n",id);
Sleep(T2*(GetRandom(1,4)));
EnterCriticalSection(&cs);
printf("Gruppo %d: abbiamo terminato di pranzare. Grazie e arrivederci\n\n",id);
pfree[table]+=nclienti;
LeaveCriticalSection(&cs);
count+=nclienti;
return 0;
}
There is one comment on this page. [Visualizza commento]