TP noté I52 2010

by Joseph Razik, on 2010-12-12

Exercice 1 (6 points)

On veut simuler le comportement d’un serveur chargé de créer une clé numérique de sécurité à partir de plusieurs nombres, chaque nombre étant stocké dans un fichier différent. On se propose de résoudre le problème de manière progressive.

Question 1

Écrire le programme ``examv1.c`` qui prend en paramètre n fichiers (on supposera que n` est un entier compris entre 2 et 10), chacun de ces fichiers contenant un entier (entre 0 et 1000). Ce programme lancera en parallèle *n processus fils, chacun devant traiter un fichier (le fils numéro 1 doit traiter le 1er fichier, le fils numéro 2 doit traiter le 2ème fichier, etc..).

Dans cette question, le traitement réalisé par chacun des fils est l’affichage à l’écran du contenu du fichier (pour cela le fils déclenchera l’exécution de la commande unix cat nomfic ). Le processus père se contentera, après avoir créé ses n fils, d’attendre la fin de chacun d’eux avant de se terminer. Vous exécuterez votre programme sur les 3 fichiers fic.txt fic2.txt fic3.txt qui sont fournis avec le sujet et se trouvent dans le répertoire /home/partage/exams.I52/.

Exemple d’exécution :

>$ ./examv1 fic1.txt fic2.txt fic3.txt
on cree fils no 1
on cree fils no 2
on cree fils no 3
SERVEUR : j'attends la fin de mes fils
Fils 1 de pid 504 : je vais traiter le fichier fic1 qui a pour contenu :567
Fils 2 de pid 505 : je vais traiter le fichier fic2 qui a pour contenu :789
Fils 3 de pid 506 : je vais traiter le fichier fic3 qui a pour contenu :122

Question 2:

Recopiez votre programme précédent ``examv1.c`` dans un autre fichier de nom ``examv2.c`` Maintenant on va remplacer le traitement réalisé par les fils dans la question précédente par un traitement plus compliqué. Chaque fils ouvre en lecture le fichier qui lui est attribué, puis lit l’entier contenu dans ce fichier, l’additionne à son PID , et enfin le transmet au père grâce à l’utilisation d’un tube (anonyme).

Le père, de son côté, lit dans le tube chaque nombre envoyé par chacun des n fils, puis additionne ces nombres pour calculer la clé finale et affiche cette clé finale à l’écran.

Remarque

on rappelle que pour ouvrir en lecture un fichier on utilise la fonction fopen(nomfic,"r") qui retourne un descripteur de fichier de type FILE * , et pour lire un entier on utilisera la fonction fscanf(fic," %d",&entier)fic est le descripteur de type FILE * retourné par fopen.

Exemple d’exécution :

>$ ./examv2 fic1.txt fic2.txt fic3.txt
PID du pere : 579
on cree fils no 1
on cree fils no 2
on cree fils no 3
Fils 1 de pid 580. nombrelu dans le fichier fic1 : 567
Reception : cle lue=1147
Fils 2 de pid 581. nombrelu dans le fichier fic2 : 789
Reception : cle lue=1370
Fils 3 de pid 582. nombrelu dans le fichier fic3 : 122
Reception : cle lue=704
SERVEUR : La cle generee est : 3221
SERVEUR : j'attends la fin de mes fils

Question 3:

Recopiez votre programme précédent examv2.c dans un autre fichier de nom examv3.c Modifiez le comportement du processus père, afin qu’à la réception d’un signal externe SIGUSR1 (donc envoyé à partir d’un terminal), il affiche à l’écran le message « J’ai reçu le signal USR1 donc je transmets la clé finale qui est xxxx » où xxxx est la valeur de cette clé finale.

Pour cela, après le calcul de la clé finale, le processus père se mettra en attente de la réception du signal que vous lui enverrez à partir d’un autre terminal.

Question 4:

Recopiez votre programme précédent examv3.c dans un autre fichier de nom examv4.c Pour finir, on veut maintenant recopier cette clé numérique en mémoire partagée, afin qu’un autre programme puisse y accéder.

Modifier votre programme précédent pour ajouter un segment de mémoire partagée permettant le stockage d’un entier. La recopie de la clé numérique en zone de mémoire partagée se fera à la réception du signal USR1. Écrivez ensuite un programme examv4b.c qui attend 10 secondes, puis envoie le signal USR1 au processus père du programme examv4, et enfin récupère l’entier se trouvant en mémoire partagée et l’affiche.

Bonus :

Exécutez vos 2 programmes dans des terminaux différents. Votre programme examv4b récupère-t-il la bonne valeur de la clé stockée en mémoire partagée ? Si non, que faudrait-il ajouter à votre programme (on ne vous demande pas de faire cette modification) ?




Exercice 2 (3 points) – Sémaphores à l’aide de tube puis d’IPC

Durant les séances de TP, vous avez pu écrire un programme permettant de simuler l’utilisation d’une unique piste d’aéroport à l’aide de sémaphores implémentés avec un tube anonyme. On vous redonne le code source de ce programme (/home/partage/exams.I52/avion_etud.c), et on vous demande de pouvoir gérer l’utilisation de cette piste d’aéroport de telle sorte qu’il y ait une alternance entre les avions qui atterrissent et ceux qui décollent. Pour simplifier le problème, on prendra comme hypothèse que le nombre d’avions qui décollent est égal au nombre d’avions qui atterrissent.

Question 1:

Recopiez le programme avion_etud.c dans un fichier de nom avion_Q1.c Modifiez le code source de telle sorte que la série alternée des avions qui décollent et atterrissent commence forcément par un avion qui atterrit.

Question 2:

Recopiez maintenant votre programme avion_Q1.c dans un fichier de nom avion_Q2.c Modifiez le code source afin de remplacer les sémaphores créés avec un tube, par des sémaphores utilisant les primitives IPC d’Unix.




Exercice 3 (5 points) La porte des étoiles

L’objectif de cet exercice est de mettre en place la gestion du raccordement d’un ensemble de « portes des étoiles » (point de communication) quand deux d’entre elles veulent établir un vortex (canal de communication) les reliant. Pour établir un vortex, la porte source doit composer l’adresse de la porte destination, adresse constituée de 7 symboles parmi 39.

Nous supposerons qu’il existe N portes, chacune étant un processus fils créé par un processus père commun. Pour simplifier le problème, un annuaire sera présent dans une zone de mémoire partagée afin de connaitre les pids (adresses) des N processus fils existants. Cet annuaire sera rempli par le processus père et sa structure est simplement un tableau des pids (entier).

Afin de rendre compte de l’état d’occupation des portes, une deuxième zone de mémoire sera présente et sera constituée de N entiers indiquant l’état d’occupation de chaque porte, dans l’ordre de correspondance des pids dans l’annuaire. Les états possibles sont les suivants:

0 : libre

1 : occupée

-1 : invalide (porte n’existant plus à cause de la terminaison du processus fils)

Le processus père effectuera les étapes principales suivantes :

  • la création et l’initialisation des zones de mémoire partagée et autre sémaphores communs,
  • la création des N processus fils,
  • le réveil des processus fils par envoi du signal SIGCONT à l’ensemble après avoir attendu 2 secondes,
  • l’attente de terminaison du dernier des N processus fils se terminant avant d’achever les fils, tout nettoyer et quitter.

Les processus fils effectueront les tâches suivantes:

  • Au commencement, chaque processus attend le signal du père indiquant que l’annuaire est prêt et que tous les fils ont été créés;
  • Au bout d’un temps aléatoire (entre 1 et 5 secondes), un processus décidera d’établir un vortex avec un autre processus. Pour cela, il choisit au hasard une adresse de destination dans l’annuaire et commence la séquence de composition. La séquence de composition consistera simplement à prendre successivement 7 jetons d’un sémaphore interne à chaque processus. Nous supposerons que la séquence de composition d’une adresse prend 7 secondes (prise du jeton puis attente d’une seconde pour enclencher le chevron associé au symbole composé). L’adresse de destination sera uniquement le pid du processus destination;
  • Une fois la séquence de composition terminée et avant d’établir un vortex, la porte source indiquera dans la seconde zone de mémoire partagée le changement d’état d’occupation des deux portes (source et destination) en mettant à 1 l’élément correspondant aux indices des deux portes. Si une porte tente d’établir un vortex avec une porte déjà occupée (valeur 1) ou une porte devenue invalide (valeur -1), l’opération est annulée (restitution des 7 jetons de sémaphore);
  • Une fois le vortex établi (changement d’état des portes validé), la porte source envoie un message SIGUSR1 à la porte destination pour lui indiquer l’ouverture d’un vortex. Le processus destination affichera un message indiquant la réception du signal;
  • Le vortex restera ouvert pendant un temps aléatoire entre 1 et 5 secondes;
  • Une fois que la source coupe le vortex, la porte source doit modifier l’état d’occupation des portes pour indiquer leur libération;
  • Chaque processus fera K tentatives de compositions d’adresse (réussies ou non) puis, ** si sa porte est libre**, le processus se terminera et placera la valeur -1 dans le tableau d’état des portes pour indiquer que sa porte est devenue invalide;
  • Le dernier processus à se terminer signale par un message SIGUSR2 au processus père que tous les processus sont terminés.

Question

Ecrire le programme stargate.c permettant cette simulation de gestion d’un réseau de porte des étoiles.

Attention:

la difficulté est aussi du point de vue algorithmique, veillez à respecter les étapes principales des processus père et fils sans en oublier. Ne pas oublier d’initialiser et détruire chaque objet IPC.

Indication:

il sera possible d’utiliser l’instruction C continue qui permet dans une boucle de passer à l’itération suivante sans exécuter le reste du code.

Exemple de trace d’exécution possible avec N=2 et K=2

Processus 12922: signal SIGCONT recu
Processus 12923: signal SIGCONT recu
Processus 12924: signal SIGCONT recu
Processus 0: tentative d'ouverture 0 de la porte 0 a 1
Processus 0: Vortex ouvert 0 1
Processus 12924 : Signal SIGUSR1 recu
Processus 1: tentative d'ouverture 0 de la porte 1 a 1
Processus 1: Impossible d'ouvrir le vortex porte source occupee 1 1 1 1
Processus 0: Vortex coupe 0 1
Processus 1: tentative d'ouverture 1 de la porte 1 a 0
Processus 1: Vortex ouvert 1 0
Processus 12923 : Signal SIGUSR1 recu
Processus 0: tentative d'ouverture 1 de la porte 0 a 0
Processus 0: Impossible d'ouvrir le vortex porte source occupee 0 0 1 1
Processus 1: Vortex coupe 1 0
Processus 1: fin du processus
Processus 0: fin du processus
Processus 12922: Signal SIGUSR2 recu