Département INFormatique 
  CSC4508/M2 : Concepts des systèmes d'exploitation et mise en œuvre sous Unix


    Évaluation



TÉLÉCOM & Management SudParis
TÉLÉCOM SudParis 2ème année

TP Noté CSC4508/M2 du 23/06/09

(2è session)

(Corrigés)

Modalités

Durée : 1 heure 30

Tous documents autorisés.

La question 1 est indépendante des questions 2 et 3. La question 3 nécessite d'avoir lu la question 2, mais pas d'y avoir répondu. Aussi, n'hésitez pas à lire tout le sujet avant de commencer pour déterminer l'ordre dans lequel vous souhaitez traiter les questions.

Le barème est donné à titre indicatif des poids entre les différentes questions.

La « livraison » de votre travail en fin de TP noté se fera par remise de votre copie à l'enseignant et par remontée sous Moodle (rubrique « TP noté de 1 heure 30 ») du fichier d'extension tgz constitué de la manière suivante :
cd votreRepertoireDeTravailPourCSC4508M2
tar cvfz $USER.tgz TPNote2009Session2

Préparation

cd votreRepertoireDeTravailPourCSC4509M2
cp ~simatic/Cours/CSC4508/tPNote2009Session2.tgz .
tar xvfz tPNote2009Session2.tgz
cd TPNote2009Session2

Question 1 : Ubunthree (10 points)

Pour chacune des questions ci-dessous, répondez sur votre copie ou bien dans le fichier Q1/reponse1.txt (dans ce dernier cas, indiquez sur votre copie « Réponse dans Q1/reponse1.txt » ).

Le nouveau système d'exploitation "Ubunthree" ne dispose que de files de message pour les communications inter-processus (il n'offre donc pas de file de tubes, de sémaphore, de moniteur ou de mémoire partagée).
Parmi les paradigmes de synchronisation de processus suivants :
  1. Exclusion mutuelle
  2. Cohorte
  3. Passage de témoins : Envoi de signaux
  4. Producteurs/consommateurs
  5. Lecteurs/rédacteurs
Choisir 4 paradigmes qui vous semblent implémentables sous "Ubunthree" avec une seule file de message.
Expliquer, sur votre copie ou bien dans le fichier Q1/reponse1.txt (dans ce dernier cas, indiquez sur votre copie « Réponse dans Q1/reponse1.txt » ) feuille, l'implémentation envisagée (5 lignes maximum par paradigme retenu).
---beginCorr
Barême : 2,5 point par paradigme
  1. L'exclusion mutuelle est implémentable de la manière suivante : on fait l'initialisation en écrivant un message (peu importe son contenu) dans la file. Quand un processus veut entrer en section critique, il lit un message dans la file (s'il y trouve un message, il le lit et donc sa lecture est passante ; s'il ne l'y trouve pas, il est bloqué dans sa lecture jusqu'à ce qu'un message soit déposé dans la file). Quand il sort de section critique, il écrit un message dans la file.
  2. La cohorte est implémentable de la manière suivante : on fait l'initialisation en écrivant autant de messages (peu importe leur contenu) dans la file qu'il y a de membres dans la cohorte. Quand un processus veut entrer dans la cohorte, il lit un message dans la file. Quand il veut en sortir, il écrit un message dans la file. NB: la cohorte ne peut pas contenir plus d'éléments que la capacité en messages de la file (il faut donc éventuellement changer la configuration de la file, si la configuration par défaut ne convient pas).
  3. L'envoi de signaux est implémentable de la manière suivante : la file est vide à l'initialisation. Pour se mettre en attente du signal, un processus lit un message sur la file (si la file est vide, le processus est donc bloqué). Pour émettre le signal, un processus écrit un message (peu importe son contenu) dans la file.
  4. Le paradigme producteurs/consommateurs est implémentable de la manière suivante : la file est vide à l'initialisation. Quand un producteur est prêt à produire, il écrit, dans la file, un message contenant les N octets de sa production. Quand un consommateur est prêt à consommer, il lit, dans le tube, un message,c e qui lui permet de récupérer les N octets à consommer.
  5. Le paradigme lecteurs/rédacteurs n'est pas implémentable avec un seul tube.
---endCorr

Question 2 : Utilisation d'une file de message dans un serveur multi-threadé (10 points)

Dans cet exercice, on considère le processus serveur étudié lors du TP noté du 19/05/2009.

On a donc un processus serveur contenant N+1 threads. L'un de ces threads, nommé distributeur, est chargé de recevoir les requêtes venant des différents clients et de communiquer ces requêtes vers l'un des N autres threads, nommés traiteurs. Ces derniers sont chargés d'effectuer le traitement de la requête et de répondre au client.
Pour simplifier l'exercice, on simule les processus clients de ce processus serveur : le thread distributeur est chargé de générer les requêtes (comme s'il les avait reçues des clients) à l'aide de la procédure simulerReceptionRequeteDeClient ; par ailleurs, dès qu'il reçoit une requête, chaque thread traiteur appelle simulerTraitementEtEnvoiReponseAuClient (qui simule notamment l'envoi du résultat du traitement de la requête au client).

Le médium de communication utilisé entre le thread distributeur et les threads traiteurs doit garantir que :
  1. aucune requête n'est perdue ;
  2. les threads traiteurs sont bloqués, en attente, quand aucune requête n'est disponible dans le médium ;
  3. le thread distributeur est bloqué, en attente, lorsque le médium est plein et ne peut donc pas recevoir une nouvelle requête.
Or, un tube est un médium de communication qui offre toutes ces garanties. C'est pourquoi, dans le code fourni en exemple, le thread distributeur communique les requêtes à traiter aux threads traiteurs via le tube distr_traite.

Avant de rentrer dans le vif du sujet, faites fonctionner ce serveur :
  • dans un terminal, positionnez-vous dans le répertoire Q2, tapez make pour compiler, puis serveur 20 pour lancer l'exécution du serveur ; le paramètre « 20 » indique le nombre de requêtes à traiter ; dans ce premier exemple, on met un nombre faible pour vérifier le bon fonctionnement en analysant visuellement la sortie ;
  • pour faire un test de performances, tapez /usr/bin/time serveur 100000 ; dans ce second exemple, on met un nombre important de requêtes à traiter pour avoir des chiffres de performance significatifs. Noter que le serveur ne fait plus aucun affichage à l'écran dès que le nombre de requêtes à traiter dépasse 100.
---beginCorr
En terme de performances, sur la machine b02-13, on obtient :
$ /usr/bin/time serveur 100000
0.18user 10.30system 0:03.59elapsed 291%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+205minor)pagefaults 0swaps

---endCorr
Pour fonctionner, ce serveur utilise 2 modules : codeEtudiant.c et simulateur.c. Mais, dans la question suivante, vous serez amené à modifier seulement codeEtudiant.c (c'est pourquoi c'est le seul module sur lequel vous avez les droits en écriture).

Dans cet exercice, on suppose qu'un profilage (profiling) a été effectué sur ce code. Il a révélé que le seul endroit où l'on peut gagner en performance au niveau de ce serveur est dans le médium de communication entre le thread distributeur et les threads traiteur. L'objectif de la question suivante est d'évaluer les performances d'une file de message IPC (et non Posix).

Modifiez Q2/codeEtudiant.c de sorte que :
  • le thread distributeur écrit ses requêtes en tant que messages dans une file de messages IPC (primitive msgsnd et non mq_send) qu'il a créée au moment de l'initialisation du programme ;
  • chaque thread traiteur lit un message sur cette file, puis appelle simulerTraitementEtEnvoiReponseAuClient avec la requête contenue dans ce message.
  • La file de message est supprimée, une fois que le programme a fini son exécution.
Une fois le code écrit et opérationnel, sur votre copie ou dans le fichier Q2/reponse2.txt, indiquez le résultat de votre test de performances. Commentez-le.
---beginCorr
Barème :
  • compilation sans warning : 1 ;
  • test du retour de chaque appel système : 1 ;
  • réponse correcte à la question posée :
    • création de la file : 2 ;
    • msgsnd : 1,5 ;
    • msgrcv : 1,5 ;
    • suppression de la file : 2
  • commentaire : 1.
voir codeEtudiant.Q2.corrige.c
En terme de performances, sur la machine b02-13, on obtient :
$ /usr/bin/time serveur 100000
0.10user 0.75system 0:00.78elapsed 109%CPU (0avgtext+0avgdata 0maxresident)k

0inputs+0outputs (0major+203minor)pagefaults 0swaps

On passe donc d'un temps d'exécution de 3.59 secondes à 0.78 secondes, soit un gain de 2,81 secondes (78%). C'est le code le plus performant obtenu parmi les codes produits ici et lors du TP noté du 19/05/2009. Les files de message IPC constituent donc un medium de communication très performant.
NB : une expérience réalisée avec les files de messages POSIX montrent que ces dernières ont un niveau de performance équivalent au files de messages IPC.
---endCorr



Page mise à jour le 23 juin 2009