// Includes #include #include #include #include #include // Constantes #define NB_PERS_MAX 100 #define NB_ATTRACTION 5 #define TIME_ATTRAC_MAX 12 #define PERS_MAX_ATTRAC 10 #define TPS_OUVERTURE_PARC 120 // Definition du type state correspondant // aux états qu'une personne peut avoir typedef enum { ARR = 0, FREE, PAY, QUIT }STATE; // Définition de la structure personne typedef struct { int id; STATE etat; int temps; // temps passé dans le parc d'attraction //float money; // Optionnel }PERSONNE; // Définition de la structure Attraction gratuite typedef struct { int id; int visite; }ATTRACTION_FREE; // Définition de la structure attraction payante typedef struct { int id; int capacite; // Capacité de l'attraction int temps; // Durée de l'attraction int visite; //float cout; // Optionnel }ATTRACTION_PAY; // Structure permmettant de stocker l'id et le nombre de visite de l'attraction la plus visitée typedef struct { int max; int id; }SEARCHMAX; // Tableau de sémaphore sem_t* sem; // Prototypes des handlers void * handlerAttrac (void*); void * handlerPers (void*); int main (void) { /// Déclarations int nbPers; int nbAttrac_P; int nbAttrac_F; int i; SEARCHMAX maxAP; SEARCHMAX maxAF; int somme = 0; PERSONNE* tabPers; pthread_t* tabThreadP; // Une personne correspond à un thread ATTRACTION_PAY* tabAttrac_P; // Une attraction payante correspond à un thread pthread_t* tabThreadAttrac_P; ATTRACTION_FREE* tabAttrac_F; // Une attraction gratuite correspond à un thread pthread_t* tabThreadAttrac_F; // Définition des nombres aléatoires // Génère un nombre aléatoire de personnes entre 1 et 100 nbPers = rand()%NB_PERS_MAX+1; // Génère un nombre aléatoire d'attraction payante entre 1 et 4 nbAttrac_P = (rand()%(NB_ATTRACTION-1)) + 1; // Les attractions qui restent sont donc gratuites nbAttrac_F = NB_ATTRACTION - nbAttrac_P; // Allocation dynamique pour les personnes tabPers = (PERSONNE*) malloc (nbPers*sizeof (PERSONNE)); tabThreadP = (pthread_t*) malloc (nbPers*sizeof (pthread_t)); // Allocation dynamique pour les attractions payantes tabAttrac_P = (ATTRACTION_PAY*) malloc (nbAttrac_P*sizeof (ATTRACTION_PAY)); tabThreadAttrac_P = (pthread_t*) malloc (nbAttrac_P*sizeof (pthread_t)); // Allocation dynamique pour les attractions gratuites tabAttrac_F = (ATTRACTION_FREE*) malloc (nbAttrac_F*sizeof (ATTRACTION_FREE)); tabThreadAttrac_F = (pthread_t*) malloc (nbAttrac_F*sizeof (pthread_t)); // Allocation dynamique du tableau de semaphore sem = (sem_t*) malloc (nbAttrac_P*sizeof (sem_t)); // Initialisation des structures personnes for (i = 0; i < nbPers; i++) { tabPers[i].id = i; tabPers[i].etat = ARR; // Toutes les personnes arrivent tabPers[i].temps = 0; // Gestion du temps passé dans le parc } // Initialisation des structures attractions payantes for (i = 0; i < nbAttrac_P; i++) { tabAttrac_P[i].id = i; tabAttrac_P[i].temps = rand()%TIME_ATTRAC_MAX+1; tabAttrac_P[i].capacite = rand()%PERS_MAX_ATTRAC+1; tabAttrac_P[i].visite = 0; } // Initialisation des structures attractions gratuites for (i = 0; i < nbAttrac_F; i++) { tabAttrac_F[i].id = i; tabAttrac_P[i].visite = 0; } puts ("Bienvenue à DigiWorld ! : OUVERTURE DES PORTES DU PARC"); // Création des threads pour les personnes for (i = 0; i < nbPers; i++) pthread_create (&tabThreadP[i], NULL, handlerPers, &tabPers[i]); // Création des threads pour les attractions payantes for (i = 0; i < nbAttrac_P; i++) pthread_create (&tabThreadAttrac_P[i], NULL, handlerAttrac, &tabAttrac_P[i]); // Création des threads pour les attractions gratuites for (i = 0; i < nbAttrac_F; i++) pthread_create (&tabThreadAttrac_F[i], NULL, handlerAttrac, &tabAttrac_F[i]); // Attente des threads for (i = 0; i < nbPers; i++) pthread_join(tabThreadP[i], NULL); for (i = 0; i < nbAttrac_P; i++) pthread_join(tabThreadAttrac_P[i], NULL); for (i = 0; i < nbAttrac_F; i++) pthread_join(tabThreadAttrac_F[i], NULL); // Expulsion des personnes for (i = 0; i < nbPers; i++) { tabPers[i].etat = QUIT; // Toutes les personnes partent somme += tabPers[i].temps; } puts ("DigiWorld : A Bientot ! : FERMETURE DES PORTES DU PARC"); // Recherche des max dans les deux types d'attractions maxAP.max = 0; maxAP.id = 0; maxAF.max = 0; maxAF.id = 0; // Attractions payantes for ( i = 0 ; i < nbAttrac_P ; i++) { if (tabAttrac_P[i].visite > maxAP.max) { maxAP.max = tabAttrac_P[i].visite; maxAP.id = i; } else { maxAP.max = maxAP.max; maxAP.id = maxAP.id; } } // Attractions gratuites for ( i = 0 ; i < nbAttrac_F ; i++) { if (tabAttrac_F[i].visite > maxAF.max) { maxAF.max = tabAttrac_F[i].visite; maxAF.id = i; } } // Résumé de la journée printf ("%d personnes ont visité le parc aujourd'hui \n", nbPers); printf ("et ont passé en moyenne %d min %d s dans le parc \n", (somme/nbPers)/60, (somme/nbPers)%60); printf ("L'attraction gratuite la plus visitée est l'attraction %d avec %d visites\n", maxAF.id, maxAF.max); printf ("L'attraction payante la plus visitée est l'attraction %d avec %d visites\n", maxAP.id, maxAP.max); // Libération de la mémoire free (tabPers); free (tabThreadP); free (tabAttrac_P); free (tabThreadAttrac_P); free (tabAttrac_F); free (tabThreadAttrac_F); return 0; } void * handlerAttrac (void* attrac) { } void * handlerPers (void* visiteur) { PERSONNE* pers = (PERSONNE*) visiteur; // TQ on ne dépasse pas le temps d'ouverture du parc while (pers->temps <= TPS_OUVERTURE_PARC) { // Selon l'état dans lequel la personne se trouve... switch (pers->etat) { case ARR : // Etat initial // Changement d'état pers->etat = (rand ()%2)+1; break; case FREE: // Etat Attraction libre // Incrémentation du temps pers->temps += (rand()%TPS_OUVERTURE_PARC)+1; // Changement d'état pers->etat = (rand ()%3)+1; break; case PAY : break; case QUIT : return; break; } } pers->etat = QUIT; return; }