La versione più recente è stata modificata il 2006-06-07 16:34:04 da DenteDiLupo [Corretta la formattazione della pagina]
Aggiunzioni:
Autolavaggio UNIX
Torna a Lab Sistemi Operativi
La versione più vecchia di questa pagina è stata modificata il 2006-06-07 14:02:39 da GiPPe []
Vista della pagina:
Ho risolto il problema d'esame del 15-02-06, insomma Autolavaggi.
Dato che è stato già risolto utilizzando i thread e mutex sotto Windows, ho pensato bene di implementarlo in Unix utilizzando le pthread e i mutex.
Di seguito il codice sorgente:
// Includo le librerie.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
// Costanti e funzioni utili
#define N 3
#define T 1
#define GetRandom( min, max ) ((rand( ) % (int)(((max) + 1) - (min))) + (min))
// Variabile che conterrà il nome del programma (inutile)
char *progname;
/* I lavaggi e l'attributo da passare all'inizializzatore del mutex! */
pthread_mutex_t hLavaggi
[N
];
pthread_mutexattr_t attr;
// UTILISSIMO!!!
/* print error message and die */
void error
(char *f
){
extern char *progname;
if (progname
)
fprintf
(stderr,
"%s: ", progname
);
perror
(f
);
exit
(1);
}
/* suspend execution of the calling thread */
void waiting
(int min,
int max
){
sleep
(rand
()%
(max-min+
1) + min
);
}
// Routine comune ad ogni thread!
void *CarRoutine
(void *param
){
int id=*
(int *
)param;
// id del thread
int type = GetRandom
(1,
2);
// tipo di macchina
if( type ==
1 ) { // caso di una macchina NORMALE
printf("T%d: Sono una macchina NORMALE! Aspetto un lavaggio!\n", id
);
while(1) { // cicla fino a trovare un lavaggio!
// se trova il lavaggio 3 libero lo blocca altrimenti non si blocca ma continua, grazie alla funzione del trylock
if ( pthread_mutex_trylock
(&hLavaggi
[2]) ==
0 ) {
printf("T%d: Sono entrato nel lavaggio 3!\n", id
);
waiting
(T*
3,T*
3);
// attende...
pthread_mutex_unlock
(&hLavaggi
[2]);
// rilascia il mutex
printf("T%d: Sono uscito dal lavaggio 3! Sono una NORMALE\n", id
);
break;
// Interrompe il ciclo
}
// vedi sopra
if ( pthread_mutex_trylock
(&hLavaggi
[1]) ==
0 ) {
printf("T%d: Sono entrato nel lavaggio 2!\n", id
);
waiting
(T*
2,T*
2);
pthread_mutex_unlock
(&hLavaggi
[1]);
printf("T%d: Sono uscito dal lavaggio 2! Sono una NORMALE\n", id
);
break;
}
// vedi sopra
if ( pthread_mutex_trylock
(&hLavaggi
[0]) ==
0 ) {
printf("T%d: Sono entrato nel lavaggio 1!\n", id
);
waiting
(T,T
);
pthread_mutex_unlock
(&hLavaggi
[0]);
printf("T%d: Sono uscito dal lavaggio 1! Sono una NORMALE\n", id
);
break;
}
} // fine ciclo while(1). la macchina è pulita!
}
if( type ==
2 ) { // caso di una macchina GRANDE
printf("T%d: Sono una macchina GRANDE! Aspetto il lavaggio 1!\n", id
);
while(1) { // cicla finche non ottiene il lavaggio 1
if ( pthread_mutex_trylock
(&hLavaggi
[0]) ==
0 ){
printf("T%d: Sono entrato nel lavaggio 1! Sono una GRANDE\n", id
);
waiting
(T,T
);
pthread_mutex_unlock
(&hLavaggi
[0]);
printf("T%d: Sono uscito dal lavaggio 1! Sono una GRANDE\n", id
);
break;
} else {
printf("T%d: Lavaggio 1 occupato! Sono una GRANDE e aspetto...\n", id
);
waiting
(T,T
);
}
}
}
return NULL;
}
// Inizia il programmino...
int main
(int argc,
char *argv
[])
{
// Inizializzo l'attributo del mutex
pthread_mutexattr_init
(&attr
);
// Mutex di tipo ERRORCHECK
pthread_mutexattr_settype
(&attr,PTHREAD_MUTEX_ERRORCHECK
);
int i;
// Struttura di un thread car
struct {
int id;
pthread_t thread_id;
} car;
// Questo è il nome del programmino
progname=argv
[0];
// Via al semeeeeeeee
srand
(time
(NULL));
/* create mutex di tipo ERRORCHECK */
for (i=
0; i<N; i++
)
if (pthread_mutex_init
(&hLavaggi
[i
], &attr
))
error
("pthread_mutex_init");
i =
0;
/* create and run the threads */
do { // Pronti...VIAAAAA
car.
id=i;
// id del prossimo thread
if (pthread_create
(&car.
thread_id,
NULL, CarRoutine, &car.
id))
error
("pthread_create");
i++;
// altro thread
} while (getchar
() !=
'q');
// finchè non presso q + invio...
return 0;
}