progsyst: publish project topic
[homepage.git] / teaching / 1415 / progsyst / projet / index.html
1 <!--?xml version="1.0" encoding="UTF-8"?-->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml"><head>
4 <link rel="stylesheet" type="text/css" href="index.css">
5 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
6   <title>Projet Programmation système 2014-2015</title>
7 </head>
8
9 <body>
10
11   <div class="bloc">
12 <h1><span style="font-weight: bold;">Projet Programmation système (M1 2014-2015)</span></h1>
13
14 <h1>Appels de Procédures Distantes, en version &laquo;&thinsp;locale&thinsp;&raquo;</h1>
15 </div>
16
17 <div class="bloc">
18 <h2>But du projet</h2>
19
20   <p>On vous demande de réaliser (en C) un système permettant à diverses
21   applications de partager leurs compétences, en autorisant chaque
22   application à faire appel à des fonctions définies par les autres. Ce
23   mécanisme est appelé <em>Remote Procedure Call</em> ou <em>RPC</em>
24   dans son cadre général &ndash; appel à des procédures définies par une
25   application tournant <em>a priori</em> sur un serveur distant. Nous
26   nous contenterons ici d'une version locale, limitée à une seule
27   machine.
28   </p>
29
30   <p>Deux modèles sont à envisager&thinsp;:</p>
31
32   <div class="ssbloc">
33     <b><big>le modèle client/serveur</big></b>
34     dans lequel un seul serveur héberge les procédures et a pour unique
35     rôle de répondre aux requêtes de calcul&thinsp;; les clients s'adressent
36     donc systématiquement au serveur pour obtenir un calcul particulier.
37   </div>
38
39   <div class="ssbloc">
40     <b><big> le modèle distribué</big></b>
41     dans lequel chaque processus fait profiter les autres de ses
42     compétences particulières&thinsp;: chacun déclare publiquement les services
43     qu'il peut offrir, et joue alternativement le rôle du client (s'il a besoin
44     de faire effectuer un calcul par un autre processus) et du serveur
45     (si un autre processus lui demande un service).
46   </div>
47 </div>
48
49 <div class="bloc">
50   <h2>Modèle client/serveur</h2>
51
52   <p>Dans ce modèle, un seul processus répond aux requêtes de calcul des autres
53   processus impliqués&thinsp;; il doit traiter toutes les requêtes reçues,
54   et renvoyer à chaque demandeur le résultat du calcul correspondant. Le
55   serveur a donc trois types de tâches à effectuer&thinsp;:
56   <ul>
57     <li> lire les requêtes<!---- (par exemple sur un tube nommé)---->&thinsp;; </li>
58     <li> exécuter les calculs nécessaires&thinsp;;</li>
59     <li> transmettre le résultat<!---- (par exemple via un &ndash; autre
60     &ndash; tube nommé)---->.</li>
61   </ul>
62   </p>
63
64   <p> Dans l'hypothèse où un client demanderait un long calcul tandis que
65   d'autres ont des requêtes plus raisonnables, il est souhaitable que le
66   serveur ne reste pas bloqué sur le gros calcul. Une solution consiste à
67   déléguer une partie du travail (choisie selon une procédure à définir)
68   à un processus fils ou à un thread pour une exécution
69   <em>asynchrone</em>. Il pourrait aussi être envisagé d'interrompre les
70   calculs trop longs.</p>
71
72   <p>
73   Le format exact des messages transmis entre les différents processus
74   n'est pas spécifié, mis à part les conventions de sérialisation de
75   certains types (voir ci-dessous). À vous de définir en particulier le
76   format des requêtes.
77   </p>
78 </div>
79
80
81 <div class="bloc">
82   <h2>Modèle distribué</h2>
83
84   <p> Dans ce modèle, tout processus peut déclarer publiquement quels
85   calculs il sait effectuer, et tout processus peut lui adresser une
86   requête en ce sens. Ce rôle de &laquo;&thinsp;serveur&thinsp;&raquo;
87   vient en parallèle du rôle premier de ces processus, qui peut
88   nécessiter une interaction avec un utilisateur. Vous pouvez par exemple
89   penser à des petites calculatrices autorisant l'utilisateur à demander
90   d'évaluer n'importe quelle expression arithmétique, alors que chacune
91   ne &laquo;&thinsp;sait&thinsp;&raquo; effectuer qu'un type d'opération.</p>
92
93   <p> Cette déclaration publique nécessite une certaine
94   centralisation, pour que les processus sachent <em>où</em> trouver
95   les informations nécessaires à un appel de fonction externe, en
96   particulier&thinsp;:
97   <ul>
98     <li> quel(s) processus offre(nt) le service souhaité&thinsp;;</li>
99     <li> par quel canal la requête doit être adressée.</li>
100   </ul>
101   </p>
102
103   <p>Pour cela, une structure de donnée adaptée sera stockée dans un segment
104   de mémoire partagée, qui contiendra l'ensemble des informations utiles. Tout 
105   processus voulant offrir un service de calcul devra le faire en
106   enregistrant les informations adéquates dans le segment de mémoire
107   partagée, aussitôt qu'il sera prêt à offrir le service. Il devra
108   prendre soin de supprimer ces informations lorsqu'il ne souhaitera plus
109   offrir ledit service.
110   </p>
111
112   <p>Ce modèle pose naturellement des problèmes de concurrence auxquels
113   il faudra trouver des solutions.
114   </p>
115 </div>
116
117
118 <div class="bloc">
119   <h2>Syntaxe d'un appel à une fonction externe</h2>
120   <p>Un appel à une hypothétique fonction
121   <code>type <var>fonction</var>(type <var>arg</var>, ...)</code>
122   devra se faire via une fonction <var>appel_externe</var> de prototype
123   (à la mode <var>execl</var>)&thinsp;:
124   </p>
125   
126   <div class="ssbloc">
127   <code>int <var>appel_externe</var>(const char *<var>fonction</var>, int
128     <var>type</var>, void *<var>retour</var>, ... /* int <var>type_i</var>,
129     void *<var>arg_i</var> */, NULL);</code>
130   </div>
131   <p>
132   ou (à la mode <var>execv</var>)&thinsp;:
133   </p>
134   <div class="ssbloc">
135   <code>int <var>appel_externe</var>(const char *<var>fonction</var>, unsigned short <var>argc</var>, struct arg *<var>argv</var>);</code> 
136   
137   </div>
138
139 <p>avec les notations suivantes&thinsp;:</p>
140 <dl>
141   <dt><var>fonction</var></dt>
142   <dd>désigne l'identificateur externe (<em>i.e.</em> le nom) de la fonction&thinsp;;</dd>
143   <dt>les éventuels <var>arg_i</var> et <var>retour</var></dt> 
144   <dd>définissent les adresses auxquelles on trouvera,  
145   à l'appel, la valeur de ses <var>arg</var>uments, et, en retour, sa valeur de <var>retour&thinsp;; </dd>
146   <dt>chaque <var>type</var></dt>
147   <dd>définit le type C de l'<var>arg</var>ument (ou du <var>retour</var>) qui suit&thinsp;;</dd>
148   <dt>le type <code>struct arg</code></dt>
149   <dd> est composé de deux champs 
150     <code>int <var>type</var></code>
151     et 
152     <code>void *<var>arg</var></code> et sert à stocker ensemble le type et
153     l'adresse d'un argument (ou du retour) de la fonction&thinsp;;
154   </dd><dt><var>argc</var></dt>
155   <dd>correspond au nombre d'éléments du tableau <var>argv</var>.</dd>
156 </dl>
157
158 </div>
159
160 <div class="bloc">
161   <h2> Constantes à définir</h2>
162
163 <p>Les différents <var>type</var>s supportés sont (au moins) les suivants&thinsp;:</p>
164 <table border="1">
165   <tbody><tr><th><var>type</var></th><th>type C</th><th>Commentaire</th></tr>
166   <tr><td><code>TYPE_VOID</code></td><td><code>void</code></td><td>ne peut apparaître que pour la valeur de retour</td></tr>
167   <tr><td><code>TYPE_INT</code></td><td><code>int *</code></td><td></td></tr>
168   <tr><td><code>TYPE_STRING</code></td><td><code>char *</code></td><td><!---ne peut apparaître comme valeur de retour---></td></tr>
169 </tbody></table>
170
171 <p>Ainsi un appel à une fonction d'addition de deux nombres entiers pourraît prendre la forme suivante&thinsp;:</p>
172 <pre>int i, j , k, r;
173 /* k = i+j; */
174 r = appel_externe("plus", TYPE_INT, &amp;k, TYPE_INT, &amp;i, TYPE_INT, &amp;j,NULL);
175 </pre>
176
177 <p>La valeur de retour de la fonction <var>appel_externe</var> représente la condition de terminaison de l'appel. On trouvera entre autres&thinsp;:</p>
178
179 <table border="1">
180   <tbody><tr><th>valeur</th><th>sémantique</th></tr>
181   <tr><td><code>APPEL_OK</code></td><td>tout s'est correctement déroulé</td></tr>
182   <tr><td><code>FONCTION_INCONNUE</code></td><td>la fonction demandée n'est pas disponible</td></tr>
183   <tr><td><code>MAUVAIS_ARGUMENTS</code></td><td>un problème concernant les arguments a été détecté (type, nombre)</td></tr>
184   <tr><td><code>PAS_DE_REPONSE</code></td><td>la fonction externe ne répond pas dans le délai imparti (5 secondes)</td></tr>
185 </tbody></table>
186 </div>
187
188 <div class="bloc">
189
190   <h2>Format de sérialisation</h2>
191
192   <p>Seul le format de sérialisation des types définis ci-dessus vous est
193   imposé&thinsp;:</p>
194
195   <table border="1">
196     <tbody>
197       <tr><th><var>type</var></th><th>codage</th><th>exemple</th></tr>
198       <tr><td><code>TYPE_VOID</code></td><td>l'octet 0x00</td><td></td></tr>
199       <tr><td><code>TYPE_INT</code></td><td>l'octet 0x01, suivi d'un octet
200           donnant la longueur <var>lg</var> de l'écriture décimale de l'entier, 
201           <br> puis 
202           des <var>lg</var> caractères de cette écriture décimale</td>
203         <td> 123 est sérialisé 0x01, 0x03, '1', '2', '3'</td></tr>
204       <tr><td><code>TYPE_STRING</code></td><td>l'octet 0x02, suivi par un
205           octet donnant la
206           longueur <var>lg</var> de la chaîne, <br>puis des <var>lg</var>
207           caractères de la chaîne &ndash; caractère nul non compris&thinsp;!</td>
208         <td>"abc" est sérialisée  0x02, 0x03, 'a', 'b', 'c'</td></tr>
209   </tbody></table>
210 </div>
211
212 <div class="bloc">
213   <h2>Instructions diverses</h2>
214
215   <p> Le projet doit être réalisé par groupes de 2 ou 3 étudiants. Les
216   groupes devront être constitués <b>le 15 mars au plus tard</b>, et ne plus
217   varier ensuite. Lors de la soutenance (qui devra naturellement être
218   bien préparée), tous les membres du groupe devront intervenir.
219   </p>
220   
221   <p> Le strict minimum à réaliser est le modèle client/serveur en mode
222   synchrone, et des retours de fonction de type <code>void</code> ou
223   <code>int</code>. Vous pouvez ensuite améliorer votre projet en
224   autorisant d'autres types de retour, en permettant un fonctionnement
225   asynchrone du serveur, et/ou en implémentant le modèle distribué. Toute
226   application originale sera naturellement appréciée à sa juste valeur.
227   </p>
228
229   <p> Votre programme devra être accompagné d'un rapport décrivant le
230   travail réalisé&thinsp;; en particulier, ce rapport devra expliquer les
231   choix que vous serez amenés à faire concernant les protocoles de
232   communication entre les différents processus.  </p>
233
234   <p> Vous devrez réaliser différents tests pour vous convaincre que
235   votre réalisation fonctionne. Décrivez-les dans votre rapport, et
236   munissez-vous du nécessaire pour convaincre les examinateurs le jour de
237   la soutenance. N'hésitez pas à mentionner <em>aussi</em> les tests
238   négatifs&thinsp;! Vous pourrez également nous montrer les
239   développements que vous avez essayé de faire sans y parvenir
240   complètement. Cependant, la version de votre projet que vous
241   présenterez doit être complètement stable.</p> 
242
243   <p> La date et les modalités de rendu seront communiquées
244   ultérieurement.</p>
245 </div>
246
247
248
249 </body></html>