/**************/ /* boursINT.c */ /**************/ /************************************************************************/ /* */ /* Numero de question qu'implemente votre code : 3.2 */ /* */ /************************************************************************/ #include #include #include #include #include #include #include #include #include #define FATAL(msg) {\ char m[128]; \ sprintf(m, "%s in %s:%d:%s", msg, __FILE__, __LINE__, __func__); \ perror(m); \ abort(); \ } /**********************************************************************/ /* Constantes */ /**********************************************************************/ #define N 9 /* Nombre de taches Surveillant */ #define SHMKEY 30 /* cle memoire partagee */ #define SEM1KEY 31 /* cle semaphore 1 */ #define SEM2KEY 32 /* cle semaphore 2 */ #define SEM3KEY 34 /* cle semaphore 4 */ /**********************************************************************/ /* Types et variables globales a tous les enfants */ /**********************************************************************/ typedef struct { int nbSurveillantTermine; double t[N]; } typDonneesPartagees; typDonneesPartagees *donneesPartagees; int topAfficheur; int topSurveillant; int mutexSurveillant; /**********************************************************************/ /* Code de P et V */ /**********************************************************************/ void P(int semId){ struct sembuf op; op.sem_num = 0; op.sem_op = -1; op.sem_flg = 0; if (semop(semId, &op, 1) == -1){ FATAL("semop"); } } void V(int semId){ struct sembuf op = {0, 1, 0}; if (semop(semId, &op, 1) == -1){ FATAL("semop"); } } /**********************************************************************/ /* Code execute par les Surveillants */ /**********************************************************************/ double surveiller(int numSurveillant){ static int numCycle = 0; numCycle += 1; sleep(1); return numCycle + numSurveillant / 10.0; // Noter le 10.0 car si on avait mis // 10, le compilateur aurait traduit // le '/' comme division *entiere* } void codeSurveillant(int numSurveillant) { do{ donneesPartagees->t[numSurveillant-1]=surveiller(numSurveillant); P(mutexSurveillant); donneesPartagees->nbSurveillantTermine += 1; if (donneesPartagees->nbSurveillantTermine == N){ // printf("\nJe libere l'afficheur\n"); V(topAfficheur); } V(mutexSurveillant); P(topSurveillant); }while(1); } /**********************************************************************/ /* Code execute par l'Afficheur */ /**********************************************************************/ double moyenne(double t[]){ double somme = 0.0; int i; for (i=0 ; it)); donneesPartagees->nbSurveillantTermine = 0; // On est sûr que l'afficheur est seul à accéder // à cette variable, car tous les // surveillants sont en attente du P qui va suivre // Donc, pas besoin de faire une exclusion mutuelle ! for (i=0 ; inbSurveillantTermine = 0; /* Creation des differents semaphores */ topAfficheur = semget(SEM1KEY, 1, IPC_CREAT|0700); if (topAfficheur < 0) { FATAL("semget"); } if (semctl(topAfficheur, 0, SETVAL, 0) < 0) { FATAL("semctl"); } topSurveillant = semget(SEM2KEY, 1, IPC_CREAT|0700); if (topSurveillant < 0) { FATAL("semget"); } if (semctl(topSurveillant, 0, SETVAL, 0) < 0) { FATAL("semctl"); } mutexSurveillant = semget(SEM3KEY, 1, IPC_CREAT|0700); if (mutexSurveillant < 0) { FATAL("semget"); } if (semctl(mutexSurveillant, 0, SETVAL, 1) < 0) { FATAL("semctl"); } /* Demarrage des taches Surveillant */ for (i=1 ; i<=N ; i++){ switch (fork()) { case -1: FATAL("fork"); break; case 0: codeSurveillant(i); break; default: break; } } /* Demarrage de la tache Afficheur */ switch (fork()) { case -1: FATAL("fork"); break; case 0: codeAfficheur(); break; default: break; } /* Attente de la demande de fin de programme */ puts("Appuyez sur la touche Entree pour faire arreter l'application"); fgets(chaineAttente,sizeof(chaineAttente),stdin); /* Suppression de tout ce qui a ete alloue */ if (shmctl(shm_id, IPC_RMID, NULL) < 0){ FATAL("semctl"); } if (semctl(topAfficheur, 0, IPC_RMID, 0) < 0){ FATAL("semctl"); } if (semctl(topSurveillant, 0, IPC_RMID, 0) < 0){ FATAL("semctl"); } if (semctl(mutexSurveillant, 0, IPC_RMID, 0) < 0){ FATAL("semctl"); } /* La suppression de tous les objets de synchronisation provoque la mort de toutes les */ /* taches (elles etaient en attente sur un objet), on recupere leur code d'erreur */ for (i=1 ; i<=N+1 ; i++){ if (wait(&status) < 0){ FATAL("wait"); } } return EXIT_SUCCESS; }