CNAM-Lorraine - ACCOV/NFP103 TD

Transcription

CNAM-Lorraine - ACCOV/NFP103 TD
CNAM-Lorraine - ACCOV/NFP103
TD-TP numéro 1
Programmation multiprocessus
S. Vialle
9 mars 2007
Ce TD-TP étudie la programmation multiprocessus au travers de plusieurs applications. L’énoncé s’articule en 6 parties de difficulté progressive :
1. Etude des méthodes de création de threads et d’allocation de sémaphores en C sous Linux ou Windows, ou en Java 1.5.
2. Conception d’un programme multithread de type producteur-consommateur
traditionnel, destiné à réaliser un prétraitement (lecture et filtrage de
fichiers) et un traitement (calcul sur les données lues) en parallèle.
3. Conception d’une variante d’un système producteur-consommateur,
où le consommateur n’est pas bloqué en cas d’absence de messages à
lire, et en profite pour poursuivre un traitement de fond.
4. Etude des méthodes de création de processus et d’allocation de sémaphores et de mémoire partagée en C sous Linux ou Windows.
5. Conception d’une application multiprocessus de gestion d’impressions,
comprenant des processus clients soumettant des impressions, et des
processus serveurs d’impression réalisant ces impressions.
6. Conception d’une application multiprocessus de gestion de mots de
passes, selon un schéma lecteurs-rédacteur.
Pour chaque exercice on rendra les listings des programmes, des exemples
d’exécution, et des explications de la démarche employée.
Les points 1 et 4 seront étudiés lors de l’implantation des codes (en TP).
Les points 2, 3, 5 et 6 seront d’abord étudiés en TD, puis repris en TP pour
y être implantés.
1
1
Création de threads et allocation de sémaphores
L’objectif de cet exercice est de vous familiariser avec la création de
threads, l’allocation de sémaphores et leur utilisation, l’attente de la mort
des threads fils, et la libération des sémaphores, dans l’environnement choisi
(C+Linux, C+Windows ou Java 1.5).
1. Implantez un programme qui crée deux threads fils. Chaque thread fils
affichera un message (”coucou”), et le thread principal (le programme
principal) attendra la mort des ses threads fils pour se terminer lui
même. Le thread principal affichera un message avant et après ce point
de synchronisation, afin que l’on puisse vérifier le bon fonctionnement
de ce premier programme multithread.
2. Déclarez une variable globale dans le programme principal (variable
globale au processus), allouer et initialiser un sémaphore binaire afin
de programmer une exclusion mutuelle. Créez deux threads fils qui
vont tous deux lire puis écrire dans la variable globale en réalisant une
exclusion mutuelle sur cette variable. Après la mort des threads fils,
libérez le sémaphore.
Affichez les résultats de tous les appels systèmes (ou attrapez toutes les exceptions) pour vérifier SYSTEMATIQUEMENT que tous les appels système
ont bien réussi.
2
2
Filtrage de fichier et traitement de données
On désire lire un fichier de données (ASCII), en supprimer les commentaires (filtrage) et réaliser un traitement sur les données extraites. La lecture
complète du fichier comportera de nombreuses opérations d’E/S, bloquantes
et longues (accès à un périphérique). Si on parallélise la lecture du fichier et
le traitement des données déjà lues, le processeur fait des calculs pendant
les temps d’attente des E/S. La figure 1 illustre ce mécanisme.
Fichiers
sur
disques
Mémoire partagée
P
C
Lecture des
fichiers
Traitement
des données
Fig. 1 – Système parallèle (multithread) de filtrage de fichiers et de traitement de données
Pour cela, une solution possible est un système de deux threads accomplissant un protocole producteur - consommateur. Un thread producteur lit
un fichier de données, le filtre, et stocke les données dans une mémoire partagée, produisant ainsi des messages à destination du thread consommateur.
Le consommateur récupère les données dans la mémoire partagée (du processus) et exécute un traitement sur chacune d’elles. Cette technique permet
normalement de gagner du temps en réalisant les E/S en parallèle de certains calculs. Mais cela peut dépendre des proportions relatives des temps
de lecture et de traitement de l’application, et des capacités matérielles de
l’ordinateur.
Travail demandé :
On implantera le système multithreads de filtrage de fichiers et de traitement de données suivant :
– Le thread producteur lit le fichier data.txt. Le producteur stocke les
entiers lus dans la mémoire partagée, et ignore les lignes de commentaires.
– Le thread consommateur récupère les entiers déposés dans la mémoire
partagée et applique sur chacun d’eux la fonction calcul(i) (à définir
rapidement, ex. : calcule récursivement la factorielle de i).
– Sur la fin du fichier, le thread producteur stocke le message -1 et
se termine. Le thread consommateur se termine à son tour quand il
3
détecte le message -1.
Le fichier de données comprendra des lignes contenant chacune un seul
entier positif, et des lignes de commentaires commençant par un 0 suivit
d’un blanc et d’un texte quelconque. La fin du fichier sera marqué par une
ligne contenant uniquement l’entier -1.
4
3
Traitement de données pilotable
Considérons un mécanisme d’acquisition et de traitement de données
en continu, mais réagissant à des commandes de l’utilisateur. En général
une saisie de commande au clavier est bloquante pour le programme qui
l’exécute, ce qui empêche de poursuivre en même temps un traitement de
fond. Avec un système à deux threads, seul celui qui saisit les commandes se
bloque en attendant une entrée au clavier. L’autre thread peut alors poursuivre ses activités, et traiter les commandes seulement lorsqu’elles arrivent
(sous forme de messages produits et stockés par le processus de saisie de
commande). La figure 2 schématise la structure d’un tel système.
Buffer partagee de messages
Traitement
de donnees
C
P
Processus de fond
(consommateur)
Interface homme−machine
(producteur)
Fig. 2 – Système (multithreads) piloté d’acquisition et de traitement de
données
Les commandes traitées peuvent être par exemple :
– halt qui termine le processus de traitement des données,
– stop qui stoppe le traitement des données s’il était actif,
– cont qui provoque la reprise du traitement s’il était stoppé,
– show qui demande au processus de traitement de fournir un bilan de
ses activités.
Travail demandé :
On implantera un système de traitement de données pilotable autour du
protocole producteur - consommateur non bloqué.
La tache de fond du consommateur sera d’appeler la procédure calcul(i) (définie précédemment). Le consommateur signalera à l’écran le nom
des commandes qu’il traitera. Dans le cas de la commande show il affichera
également la valeur du paramètre passé à la procédure calcul lors de son
dernier appel.
5
4
Création de processus et allocation de sémaphores et de mémoire partagée
Après une programmation de systèmes multithreads, l’objectif de cet
exercice est de vous familiariser avec la création de processus et l’allocation
et libération de zones de mémoire partagée entre plusieurs processus au sein
d’un même ordinateur.
1. Implantez deux applications (deux programmes distincts) qui allouent
ou récupèrent une zone de mémoire partagée et allouent un même sémaphore binaire. L’une des deux applications sera appelée le ”serveur”
et sera lancée en premier (elle fera l’initialisation du sémaphore et de
la mémoire partagée). La deuxième sera appelée le ”client”.
2. Les deux processus liront et écriront dans la mémoire partagée en
implantant une exclusion mutuelle sur la variable accédée concurremment.
3. Le client finira par entrer dans la mémoire partagée une valeur que
le serveur reconnaı̂tra comme un code d’arrêt. Dès lors le client ne
manipulera plus le sémaphore ni la mémoire partagée (il s’arrêtera),
et le serveur libérera la mémoire partagée et le sémaphore, et s’arrêtera
à son tour.
Comme précédemment, vous afficherez systématiquement le résultat des appels systèmes, pour vérifier leur bonne exécution.
6
5
Simulateur de spooling
On considère un système de gestion d’impressions disposant de plusieurs
imprimantes. On désire pouvoir lancer des impressions en parallèle depuis
plusieurs terminaux, et que chacune soit exécutée le plus rapidement possible
sur n’importe quelle imprimante libre. On supposera les imprimantes toutes
regroupées dans la même salle . . .
Imprimantes
Spooler
(demon)
Spooler
(demon)
Spooler
(demon)
Demons
d’impressions
Memoire
partagee
Utilisateurs
demandant
des impressions
Fig. 3 – Exemple de système de gestion d’un parc d’imprimantes
Il s’agit d’un système de P processus déposant des demandes d’impression (imprime), et de C processus démons gérant chacun une imprimante et
réalisant des impressions (imprimed), voir figure 3. Le protocole correspondant est du type P producteurs et C consommateurs, accédant tous à une
mémoire partagée où sont stockées les demandes d’impressions.
Travail demandé :
On écrira une commande de demande d’impression et un programme de
démon d’impression, respectivement imprime et imprimed.
La commande d’impression prendra comme seul paramètre un entier
qui représentera l’identificateur du fichier. Cet entier sera récupéré depuis la
ligne de commande. L’exécution de la commande imprime consistera à simuler une demande d’impression. Pour cela elle déposera un message constitué
de l’identificateur du fichier, et exécutera une attente (sleep(20)) dans sa
7
section critique. De plus elle signalera à l’écran son entrée et sa sortie de
section critique.
Le démon d’impression prendra comme seul argument le nom de l’imprimante qu’il gérera (passé par la ligne de commande). Le travail d’un démon
consistera à consommer des messages et à simuler des impressions. Pour cela
il affichera l’identificateur du fichier qu’il imprime (le message), et exécutera
une attente (sleep(30)) dans sa section critique. De plus il affichera son
entrée et sa sortie de section critique. Par convention dans le TL, un démon
d’impression se terminera après avoir effectué 3 impressions.
On ouvrira une fenêtre de commande pour chaque imprimante que l’on
voudra simuler, dans lesquels on lancera le démon correspondant, et quelques
fenêtres de commande dans lesquelles on effectuera des demandes d’impressions. On vérifiera le bon fonctionnement de l’ensemble.
8
6
Gestionnaire de password
Considérons un système informatique dans lequel un groupe d’utilisateurs accèdent à un service via un programme leur demandant au départ un
mot de passe. Ce mot de passe sera le même pour tout le groupe. Ce pourrait
être par exemple un service de documentation payant et forfaitaire auprès
duquel une société aurait souscrit un abonnement d’un mois, renouvelable.
Tous les employés de la société pourraient accéder à ce service en entrant le
mot de passe, éventuellement en même temps, mais seulement pendant un
mois. La figure 4 illustre ce système.
Utilisateurs
Disque et
fichiers des
mots de passe
Maitre
Fig. 4 – Système d’interrogation et de gestion d’un service de documentation
Pour ce type de prestation c’est la société offrant le service de documentation qui impose le mot de passe et le change tous les mois. Le nouveau
mot de passe n’est communiqué à la société cliente que si elle renouvelle son
abonnement. Donc, le fichier conservant le mot de passe du client est accédé
régulièrement en lecture à chaque consultation de la part du client, et de
temps en temps en écriture par la société de documentation pour changer
autoritairement le mot de passe. Toutefois un mot de passe ne peut être
changé qu’à condition qu’il n’y ait pas d’utilisateurs en train de le consulter
à cet instant.
Il s’agit d’un protocole de type lecteurs - rédacteur, sur un fichier de
mots de passe, avec priorité simple aux lecteurs.
Travail demandé :
On réalisera un programme client testant la validité d’un mot de passe
saisi au clavier, et un programme maitre permettant de changer le mot de
passe. Le programme client se terminera immédiatement en cas de saisie
9
incorrecte du mot de passe, et sur l’entrée de ’quit’ en cas de connexion
réussie.
On ouvrira une fenêtre de commande dans laquelle on exécutera un
programme maitre pour définir un premier mot de passe. Puis, on ouvrira ensuite plusieurs fenêtres de comamnde dans lesquelles on établira
des connexions au service de documentation en exécutant des programmes
client. On changera ensuite le mot de passe en exécutant un nouveau programme maitre, et on vérifiera que les futures connections dépendent bien
du nouveau mot de passe.
Les programmes client et maitre maintiendront le fichier passwd ouvert durant toute la saisie du mot de passe au clavier. Ceci imposera une
section critique importante permettant de vérifier aisément les deux règles
suivantes :
– Plusieurs programmes client peuvent accéder au fichier passwd en
même temps.
– Un programme maitre réalise un accès exclusif au fichier passwd, ne
pouvant y accéder que s’il n’y a plus d’utilisateurs connectés, et empêchant toute connexion d’utilisateur pendant le changement de mot
du passe.
10