/* * Programme simulant la gestion d'une imprimante * Dans cette version, on a un processus client (imprime6c) qui envoie * ses requetes d'Impression a un processus serveur (imprime6s) via une * zone de memoire partagee et un mecanisme de producteur/consommateur * De plus, imprime6l est en mesure de lire le contenu du tampon de * la zone de memoire partagee pour afficher les travaux en attente */ #include #include #include #include #include #include #include #include #include "imprime6.h" /* Memoire partagee */ shm_t *shm; /* Code d'affichage des travaux en attente */ void affichageTravauxEnAttente(){ int i; int nbJobs; int val; int rc; printf("Debut liste des travaux en attente\n"); /* Calcul du nombre de jobs en attente En effet, on ne peut pas faire une bete boucle for (i = shm->iExtrait ; i != shm->iDepot ; i = (i+1)%NBMAXNOMFIC) { qui, quand iDepot == iExtrait ne peut pas faire la difference entre un tampon shm plein de noms de fichiers a imprimer et un tampon shm vide de noms de fichier a imprimer On doit donc lire la valeur du semaphore placeDispo qui nous permettra de connaitre le nombre de noms de fichiers presents dans le tampon (NB : lire directement infoPrete serait moins fiable car on peut avoir des consommateurs qui ont deja fait le sem_wait(info_prete) et sont donc entrain de travailler sur un nom de fichier) */ rc = sem_getvalue(&shm->place_dispo, &val); assert(rc == 0); nbJobs = NBMAXNOMFIC - val; /* On peut maintenant faire l'impression */ for (i = 0 ; i < nbJobs ; i++) { printf("Fichier \"%s\" en attente d'impression\n", shm->nomFic[(shm->iExtrait + i) % NBMAXNOMFIC]); } printf("Fin liste des travaux en attente\n"); } /* Programme pricipal */ int main(){ int fd; /******************/ /* Initialisation */ /******************/ /* Recuperation pointeur sur la mémoire partagee (crees par imprime6s) */ fd = shm_open(CLE_SHM, O_RDWR, 0666); assert(fd>=0); assert(ftruncate(fd, sizeof(shm_t)) >= 0); shm = mmap(NULL, sizeof(shm_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); assert(shm>=0); /************************************/ /* Affichage des travaux en attente */ /************************************/ sem_wait(&shm->fifo); sem_wait(&shm->mutexl); shm->nbLec += 1; if (shm->nbLec == 1) { sem_wait(&shm->mutexg); } sem_post(&shm->mutexl); sem_post(&shm->fifo); affichageTravauxEnAttente(); sem_wait(&shm->mutexl); shm->nbLec -= 1; if (shm->nbLec == 0) { sem_post(&shm->mutexg); } sem_post(&shm->mutexl); return EXIT_SUCCESS; }