void Initialisation () { /** Création des clefs pour les IPC **/ key_t cleBalEntreeBPP = ftok(CHEMIN,1); key_t cleBalEntreeBPA = ftok(CHEMIN,2); key_t cleBalEntreeGB = ftok(CHEMIN,3); key_t cleBalSortie = ftok(CHEMIN,4); key_t cleMPNbPlace = ftok(CHEMIN,5); key_t cleMPEtat = ftok(CHEMIN,6); key_t cleMPRequete = ftok(CHEMIN,7); key_t cleSem = ftok(CHEMIN,8); /** Fin création des clefs pour les IPC **/ /** Création des BaL **/ if ((baLEntreeBPP = msgget(cleBalEntreeBPP, 0666|IPC_CREAT)) == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour l'entrée BPP (BAL)"); #endif } if ((baLEntreeBPA = msgget(cleBalEntreeBPA, 0666|IPC_CREAT)) == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour l'entrée BPA (BAL)"); #endif } if ((baLEntreeGB = msgget(cleBalEntreeGB, 0666|IPC_CREAT)) == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour l'entrée GB (BAL)"); #endif } if ((baLSortie = msgget(cleBalSortie, 0666|IPC_CREAT)) == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour l'entrée Sortie (BAL)"); #endif } /** Fin création des BaL **/ /** Création des MP **/ //Initialisation de la memoire partagee NbPlaceOccupees mpNbPlace = shmget(cleMPNbPlace,sizeof(NbPlaceOccupees), 0666|IPC_CREAT); if ( mpNbPlace == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour MP nbPlace"); #endif } else { NbPlaceOccupees *nbo = (NbPlaceOccupees *) shmat(mpNbPlace, NULL, 0); nbo->nb = 0; shmdt(nbo); } //Initialisation de la memoire partagee Etat if ((mpEtat = shmget(cleMPEtat,sizeof(Etat), 0666|IPC_CREAT)) == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour MP Etat"); #endif } else { Etat *et = (Etat *) shmat(mpEtat, NULL, 0); for(unsigned int i=0; i < NB_PLACES ; i++) { et->places[i] = {AUCUN, 0,0}; } shmdt(et); } //Initialisation de la memoire partagee Requete mpRequete = shmget(cleMPRequete,sizeof(Requete), 0666|IPC_CREAT); if ( mpRequete == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur pour MP Requete"); #endif } else { Requete *req = (Requete *) shmat(mpRequete, NULL, 0); for(unsigned int i=0; i < NB_BARRIERES_ENTREE; i++) { req->requetes[i] = {AUCUN, 0,0}; } shmdt(req); } /** Fin création des MP **/ /** Création des sémaphores **/ if ((semGene = semget(cleSem,NB_SEM,0666|IPC_CREAT)) == -1) { #ifdef MAP AFFICHER(MESSAGE,"Erreur de création de sémaphore"); #endif } else { semctl(semGene,SynchroPorteBPPROF,SETVAL,0); semctl(semGene,SynchroPorteBPAUTRE,SETVAL,0); semctl(semGene,SynchroPorteGB,SETVAL,0); semctl(semGene,MutexMPNbPlaces,SETVAL,1); semctl(semGene,MutexMPEtat,SETVAL,1); semctl(semGene,MutexMPRequetes,SETVAL,1); } /** Fin création des sémaphores **/ heure = ActiverHeure(); if ((clavier = fork()) == 0) { SimulationClavier( baLSortie, baLEntreeBPP, baLEntreeBPA, baLEntreeGB); } else if ((entreeBPP = fork()) == 0) { PorteEntree( baLEntreeBPP, semGene, mpNbPlace, mpEtat, mpRequete, PROF_BLAISE_PASCAL); } else if ((entreeBPA = fork()) == 0) { PorteEntree( baLEntreeBPA, semGene, mpNbPlace, mpEtat, mpRequete, AUTRE_BLAISE_PASCAL); } else if ((entreeGB = fork()) == 0) { PorteEntree( baLEntreeGB , semGene, mpNbPlace, mpEtat, mpRequete, ENTREE_GASTON_BERGER); } else if ((sortie = fork()) == 0) { PorteSortie(mpNbPlace, mpEtat, mpRequete, baLSortie, semGene); } }
int main ( void ) // Mode d'emploi : // Gère la création et la destruction de tous les composantes de // l'application, et tourne tant que le simulateur n'a pas renvoyé. // // Contrat : // (Aucun) // // Algorithme : // Initialise les composantes fournies pour le TP, puis crée tous les // mécanismes IPC (sémaphores, files de message et la mémoire partagée). // Chaque tâche est ensuite lancée une par une, le simulateur étant // lancé en dernier pour éviter que l'utilisateur lance des demandes // avant que toute l'application ne soit prête. // La tâche tourne ensuite à l'infini tant que le simulateur ne renvoie // pas, avant de demander la terminaison de chaque tâche en cours puis // la suppression des mécanismes IPC. Finalement, l'affichage est // terminé et l'application termine. // { /* --- Initialisation --- */ // Initialisation de l'application #ifdef AFFICHAGE_XTERM enum TypeTerminal terminal = XTERM; #else // AFFICHAGE_XTERM enum TypeTerminal terminal = VT220; #endif // AFFICHAGE_XTERM InitialiserApplication(terminal); size_t MAX_TACHES = NB_BARRIERES + 2; pid_t tachesPid[MAX_TACHES]; size_t taches = 0; // Initialiser les files de message int filesId[NB_BARRIERES]; for (size_t i = 0; i < NB_BARRIERES; i++) { filesId[i] = msgget(CLE_BARRIERES[i], IPC_CREAT | DROITS); } // Initialiser le sémaphore du mutex à 1 (car il n'est pas en cours // d'utilisation) et les sémaphores des barrières à 0 (car il n'y a aucune // requête en cours). int semId = semget(CLE_SEMAPHORE, NUM_SEMAPHORES, IPC_CREAT | DROITS); semctl(semId, SEM_MUTEX, SETVAL, 1); semctl(semId, SEM_PBP, SETVAL, 0); semctl(semId, SEM_ABP, SETVAL, 0); semctl(semId, SEM_EGB, SETVAL, 0); // Initialiser la mémoire partagée avec aucune place occupée et aucune // requête envoyée int shmId = shmget(CLE_MEMOIRE_PARTAGEE, sizeof(memoire_partagee_t), IPC_CREAT | DROITS); memoire_partagee_t * mem = (memoire_partagee_t *) shmat(shmId, NULL, 0); mem->placesOccupees = 0; for (size_t i = 0; i < NB_PLACES; i++) { mem->places[i] = PLACE_VIDE; } for (size_t i = 0; i < NB_BARRIERES_ENTREE; i++) { mem->requetes[i] = REQUETE_VIDE; } shmdt(mem); // Lancer toutes les tâches tachesPid[taches++] = ActiverHeure(); if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière S (Sortie) BarriereSortie(SORTIE_GASTON_BERGER); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière Entrée (Blaise Pascal - Profs) BarriereEntree(PROF_BLAISE_PASCAL); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière Entrée (Blaise Pascal - Autres) BarriereEntree(AUTRE_BLAISE_PASCAL); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière Entrée (Gaston Berger) BarriereEntree(ENTREE_GASTON_BERGER); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Simulateur Simulateur(); } else { // Père /* --- Moteur --- */ waitpid(tachesPid[--taches], NULL, 0); /* --- Destruction --- */ while (taches) { kill(tachesPid[--taches], SIGUSR2); } semctl(semId, 0, IPC_RMID, NULL); shmctl(shmId, IPC_RMID, NULL); for (size_t i = 0; i < NB_BARRIERES; i++) { msgctl(filesId[i], IPC_RMID, NULL); } TerminerApplication(true); exit(0); } } } } } return 0; }