|
|
Institut National des Télécommunications
Télécom INT 2è année
TP Noté CS21 du 22/06/04
(2è session)
Modalités
Durée : 1 heure 30
Tous documents autorisés
Les questions sont indépendantes les unes des autres.
Le barême est donné à titre indicatif des poids entre les différentes
questions. Seront notés :
- La clarté du code,
- Le fait que le code compile (sans warning),
- Le fait que le code répond correctement à la question posée,
- Le fait que le retour de chaque appel système, s'il y en a un,
est testé et géré (traitement d'erreur)
,
- Le fait que les ressources système réservées pendant l'exécution
du programme sont libérées à la fin de l'exécution.
La «livraison» de votre travail en fin de TP noté se fera par remise de
votre copie à l'enseignant et par
envoi d'un mail à frederique.silber-chaussumier@int-evry.fr
(sujet «CS21:TPNoteSession2») avec en pièce jointe le fichier
d'extension
tgz constitué de la manière suivante :
cd votreRepertoireDeTravailPourCS21 tar cvfz $USER.tgz TPNote2004Session2
Préparation
Question 1 : O_SYNC (4 points)
man 2 open décrit le rôle de l'option O_SYNC
dans l'appel système open .
Q1.1 : Pourquoi n'utilise-t-on pas cette option en général ?
Q1.2 : Donner un exemple d'application où cette option est requise.
NB : Vous pouvez répondre sur votre copie ou bien dans le fichier Q1/reponse.txt
(dans ce dernier cas, indiquez sur votre copie "Réponse dans Q1/reponse.txt ").
Question 2 : Concurrence d'accès (8 points)
Le module suivant est utilisé pour gérer une liste chaînée de données.
#include <stdlib.h>
/* Structure utilisee pour stocker
les
differents elements de la liste */
typedef struct element_t{
/* Donnees stockees dans cet
element de la liste chainee */
char data[256];
/* Pointeur vers l'element suivant
de la liste chainee (NULL si pas */
/* d'element suivant)
*/
struct element_t *next;
} element_t;
/* Pointeur sur le premier element de la liste
chainee
*/
static element_t *first=NULL;
/* Ajoute l'element unElement en tete de liste chainee */
void addFirst(element_t *unElement){
/* Comme unElement va etre insere en tete de liste,
*/
/* son successeur sera le premier element actuel de la
liste */
unElement->next = first;
/* La nouvelle tete de liste est unElement */
first = unElement;
}
Dans un programme mono-thread,
ce module donne entière satisfaction.
En revanche, dans le cas d'un programme contenant deux threads (qui appellent à certains
moments la fonction addFirst ), chacun ayant une politique
d'ordonnancement FIFO, l'un
ayant une priorité statique égale à 1, l'autre ayant une priorité
statique égale à 2, on constate qu'addFirst perd des
éléments.
Q2.1 : Pourquoi ?
Q2.2 : Aurait-on ce bug si les deux threads avaient la même priorité
statique (comprise entre 1 et 99) ? Justifier votre réponse.
Q2.3 : Proposer, dans ses grandes lignes, une solution pour le bug d'addFirst
quand les deux threads ont une priorité statique différente.
NB : Vous pouvez répondre sur votre copie ou bien dans le fichier Q2/reponse.txt
(dans ce dernier cas, indiquez sur votre copie "Réponse dans Q2/reponse.txt ").
Question 3 : Tube versus mémoire
partagée
(8 points)
On souhaite comparer les performances des communications à travers un
tube et celles à travers une zone de mémoire partagée synchronisée
selon un paradigme
producteur/consommateur.
Pour ce faire, on se propose de coder le programme Q3/tube.c
(respectivement Q3/memoirePartagee.c ) selon l'algorithme
suivant
- Création d'un tube (respectivement d'un tampon et des entités
liées au paradigme producteur/consommateur)
- Création d'un enfant
- Déclaration d'une variable
s de type structure_t
- Initialisation de tous les octets de
s à '\0'
- répéter
NBECHANGES fois
- Envoyer
s à l'enfant via le tube (respectivement
la zone de mémoire partagée)
- Fin Répéter
- Attendre décès de l'enfant
Dans ce programme, le fils effectue l'algorithme suivant :
- Définir une variable
s de type structure_t
- répéter
NBECHANGES fois
- Lire la valeur de
s envoyée par le père via le
tube (respectivement la zone de mémoire partagée)
- Fin Répéter
Question 3.1 : Codage de Q3/tube.c
Le programme Q3/memoirePartagee.c est déjà fourni.
Compléter les lignes /*** A completer ***/ de Q3/tube.c
pour qu'il fonctionne conformément à l'algorithme ci-dessus.
NB : même si vous n'arrivez pas à répondre à cette question, vous
pouvez quand même travailler sur la question Q4.2.
Question 3.2 : Analyse
Dans le fichier Q3/commentaire.txt :
- Q3.2.1. Indiquer le résultat de la commande
/usr/bin/time
appliqué à Q3/memoirePartagee et Q3/tube
(ou Q3/tubeSiQ31KO
si vous n'avez pas pu répondre à la question Q3.1)
- Q3.2.2. Les résultats obtenus militent en faveur de l'utilisation
systématique des tubes. En remarquant que le nombre d'octets contenus
dans un tube n'est pas aisément paramétrables (recompilation du noyau
requise), citer une situation où on préférera utililiser de la mémoire
partagée plutôt que des tubes (même si les performances sont moins
bonnes).
Q3.2.3. La différence de temps d'exécution peut surprendre.
Expliquer pourquoi : on ne demande pas d'expliquer la différence de
temps d'exécution en elle-même (il faudrait analyser le code du noyau
Linux pour comprendre la gestion des tubes et de la mémoire partagée),
mais on demande d'expliquer en quoi la différence de temps d'exécution
est surprenante.
NB :
cette question est plus difficile que les autres. Il est donc
recommandé de ne l'aborder que quand vous avez traité les autres
questions.
|