TÉLÉCOM SudParis 2ème
année
TP Noté CSC4508/M2 du 16/05/12
Modalités
Durée : 3 heures
Tous documents autorisés.
Les questions 1, 2 et 3 sont indépendantes les unes des autres. 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
remontée sous Moodle (rubrique « TP noté de 3 heures ») du fichier
d'extension tgz constitué de la manière suivante :
cd votreRepertoireDeTravailPourCSC4508M2 tar cvfz ${USER}.tgz ${USER}_TPNote2012
NB: Si vous êtes plus à l'aise en écrivant vos réponses sur une copie
plutôt qu'en les tapant sur ordinateur, vous pouvez rendre également
une copie papier à l'enseignant qui vous surveille. En fin d'épreuve,
même si vous ne rendez pas de copie, passez voir l'enseignant qui vous
surveille pour lui signaler explicitement que vous ne rendez pas de
copie.
Préparation
cd votreRepertoireDeTravailPourCSC4508M2 cp ~trahay_f/Cours/CSC4508/tPNote2012.tgz . tar xvfz tPNote2012.tgz mv TPNote2012 ${USER}_TPNote2012
cd ${USER}_TPNote2012
Question 1 : Questions de cours (4 points)
Pour chacune des questions ci-dessous, répondez dans le fichier
Q1/reponse1.txt ou bien sur votre copie (dans ce dernier
cas, indiquez dans le fichier Q1/reponse1.txt « Réponse
sur copie »).
Question 1.1 : Mémoire dans un processus multi-threadé (3
points)
On considère la portion de code suivante issue d'un programme
multi-threadé :
int a;
static int b;
int foo() {
int
c;
static int d;
char
*e = malloc(sizeof(char) * 80);
char
*f = alloca(sizeof(char) * 80);
...
}
Expliquez en justifiant brièvement si, pour chacune des variables
a , b , c et d , il
s'agit d'une variable partagée entre les différents threads du
programme ? Dit autrement, si un thread change la valeur de
cette variable, un autre thread voit-il le changement ?
Même question pour les zones de données pointées par e
et f .
: 0.5 point par proposition (0,25 pour la justesse de la réponse
Question 1.2 : 640 Ko de mémoire devraient suffire à tout le monde
(1 points)
Le développeur d'une application destinée à faire l'inventaire dans un
supermarché réfléchit actuellement à la structure de données à utiliser
pour son programme. Il compte utiliser cette structure :
struct object{
int identifiant;
char code_barre[10];
int nombre;
};
Comme la machine sur laquelle fonctionnera l'application dispose de
très peu de mémoire et que le nombre d'objets à créer dans
l'application est très grand, le développeur souhaite minimiser la
taille mémoire occupée par chaque objet.
Modifiez cette structure (sans en modifier les champs) pour
minimiser la taille d'un objet.
: 1 point
Question 2 : Passer le gué (8 points)
Les ponts permettant de traverser la Bruinen sont rares et il est
parfois nécessaire de prendre une barge (un bateau à fond plat) pour
traverser la rivière. À l'Est d'un village peuplé d'elfes se trouve une
barge permettant de traverser la rivière et ainsi accéder à la forêt
située de l'autre côté pour y cueillir les framboises dont raffolent
les elfes. Cette barge est située à l'Ouest du village des nains et
ceux-ci l'empruntent pour se procurer leur bière préférée produite par
un brasseur habitant près du village elfe.
Le propriétaire de la barge n'accepte de traverser que si 4
passagers montent à bord et comme les elfes et les nains entretiennent
de mauvaises relations, il ne peut y avoir 1 elfe et 3 nains, ni 3
elfes et 1 nain, sous peine de bagarre générale. Les autres
combinaisons (4 nains seuls, 4 elfes seuls, ou 2 nains et 2 elfes) ne
posent pas de problème.
L'objectif de cet exercice est de simuler la circulation des nains
et des elfes. Pour cela, chaque elfe ou nain de l'histoire est
représenté par un thread.
Lorsqu'un thread (elfe ou nain) monte sur la barge, il doit
appeler la fonction embarquer . Il faut garantir que 4
threads ont appelé embarquer avant que les
threads de la traversée suivante n'embarquent.
Lorsque les 4 threads ont embarqué, l'un d'eux (peu importe
lequel) doit appeler la fonction ramer . On appelle le
thread chargé de ramer le
Capitaine .
Pour chacune des questions ci-dessous :
- Répondez dans le fichier
Q2/reponse2.txt ou bien sur
votre copie (dans ce dernier cas, indiquez dans le fichier
Q2/reponse2.txt « Réponse sur copie »).
- Le langage algorithmique utilisé n'a pas besoin de respecter
strictement la syntaxe apprise en première année. L'essentiel est
qu'il soit lisible par le correcteur et sans ambiguïté.
- Les questions 2.1 et 2.2 sont indépendantes.
Question 2.1 : Implémenter une barrière (3 points)
On souhaite dans un premier temps implémenter une "barrière" à
partir d'un ou plusieurs sémaphores permettant d'attendre que les 4
threads aient embarqué. Une barrière est un point de
synchronisation qui garanti que N tâches sont arrivées à un point
spécifique. Lorsqu'un thread atteint la barrière, il attend
jusqu'à ce que le nombre de thread requis soit atteint.
À l'aide de sémaphores (dont vous indiquerez les valeurs initiales),
d'éventuelles variables additionnelles (dont vous indiquerez les
valeurs initiales), et d'opérations P() et V(), écrivez l'algorithme de
barriere().
Question 2.2 : Algorithme du passage de la Bruinen (5 points)
Chaque nain est modélisé par un thread exécutant l'algorithme
codePassageNain() .
Chaque elfe est modélisé par un thread exécutant un algorithme
codePassageElfe()
similaire.
procédure
codePassageNain()
je_suis_capitaine = faux;
// à compléter, si besoin, avec du code d'initialisation
et de synchronisation
embarquer( );
// à compléter, si besoin, avec du code de synchronisation
barriere( );
// à compléter, si besoin, avec du code de
synchronisation
si je_suis_capitaine alors
// à compléter, si besoin, avec
du code de synchronisation
ramer();
// à compléter, si besoin,avec du code de
synchronisation
Fin Si
Fin Procédure
À l'aide de sémaphores (dont vous indiquerez les valeurs initiales),
d'éventuelles variables additionnelles (dont vous indiquerez les
valeurs initiales), et d'opérations P() et V(), complétez l'algorithme de
codePassageNain().
: 5 points
Question 3 : Remote Procedure Calls (8 points)
NB : Pour certaines des questions ci-dessous, vous êtes conviés à
répondre dans le fichier Q3/reponse3.txt . Si vous
préférez répondre sur votre copie, indiquez dans le fichier
Q3/reponse3.txt « Réponse sur copie ».
Le but de cet exercice est de développer un système de RPC (Remote
Procedure Call) permettant d'appeler des fonctions dans un processus
distant. Un serveur founi un ensemble de fonctions qu'il peut exécuter
à la place de l'application cliente. Par exemple, si une application
souhaite calculer la somme de deux vecteurs, elle peut le demander au
serveur qui lui retourne le résultat.
Protocole
À l'initialisation, le serveur crée un tube nommé
./serveur-rpc (noté Ts dans la suite) et attend
que des applications clientes se connectent et donnent des ordres.
Lorsqu'un ordre est reçu, le serveur traite la requête, puis attend un
nouvel ordre.
Lorsqu'une application souhaite exécuter une fonction sur le
serveur, elle envoie le numéro de la fonction à exécuter sur le tube
Ts. Elle ouvre ensuite un nouveau tube (de la forme
/tmp/client-rpc.<PID> , noté Tc dans la
suite) pour que le serveur puisse lui répondre et envoie le nom de ce
tube sur Ts. Selon la fonction à exécuter, le serveur attend
alors que l'application envoie les paramètres de la fonction. Une fois
le calcul effectué sur le serveur, celui-ci envoie le résultat sur
Tc et ferme la connexion.
Question 3.1 (2.5 points)
Compléter dans le répertoire Q3/Q3.1 les fichiers
client. c et serveur.c pour gérer la création
des tubes, l'établissement et la fermeture de la connexion entre
serveur et client (parties A COMPLETER dans le code).
Testez votre serveur avec 1 client.
:
Question 3.2 (1 point)
En testant le serveur avec plusieurs client, un problème se pose.
Ainsi, si vous tapez dans un terminal : for ((i=1;i<=30;i+=1)); do (./client
&);done
vous risquez d'obtenir l'affichage suivant du coté serveur :
[...]
En attente...
Traitement d'une requete MUL
Calcul de mul(14.500000, 18.500000)
En attente...
Traitement d'une requete SOMMEV
Calcul de sommv(taille des vecteurs: 10)
En attente...
Traitement d'une requete SOMME
Calcul de somme(14.500000, 0.000000)
En attente...
Traitement d'une requete inconnue (1886221359)
En attente...
Traitement d'une requete inconnue (762605157)
En attente...
open(nomtube): No such file or directory
Expliquer, dans le fichier Q3/reponse3.txt, la raison de ce
problème.
Question 3.3 (2.5 points)
Proposer, dans le fichier Q3/reponse3.txt , une solution
qui permettrait de résoudre se problème
Question 3.4 (2 points)
Implémentez votre solution en modifiant les fichiers
client.c et serveur.c situés dans le
répertoire Q3/Q3.4 .
Vérifier que votre serveur peut désormais gérer un grand nombre de
clients en parallèle en tapant dans un terminal: for ((i=1;i<=30;i+=1)); do (./client
&);done
|