ESIEE I3 IN301/IN3ST01 

Systèmes d'exploitation - UNIX

TD-Machine : Processus sous Unix

Objectifs

  1. Comprendre et mettre en oeuvre le mécanisme de création de processus en C sous Linux
  2. Comprendre et mettre en oeuvre une première solution de synchronisation entre un processus père et son fils
  3. Comprendre et mettre en oeuvre la notion de recouvrement de processus
  4. S'initier à la lecture/écriture de fichiers avec les appels systèmes Linux
  5. Débuter la programmation de bibliothèques utiles pour le projet IN3(ST)01

Remarques préliminaires : environnement de développement : make et gcc

I - Affichage avec caractéristiques d'un processus & synchronisation père-fils

Lorsque plusieurs processus s'exécutent simultanément, il est difficile de savoir quelle ligne a été imprimée par chacun d'entre eux à l'écran. L'objectif de ce premier exercice est d'implémenter une bibliothèque (appelée par exemple affichage-processus) qui facilite la lecture des messages à l'écran dans un contexte multi-processus.

A - Dans cette bibliothèque vous implémenterez 3 fonctions C, prenant en paramètre une chaîne de caractère et affichant :

1) La chaîne de caractère précédée du numéro d'identification du processus.
2) La chaîne de caractère précédée du numéro d'identification de son père.
3) La chaîne de caractère précédée des deux informations ci-dessus.

B- Dans trois autres fichiers C distincts vous implémenterez trois fonctions main permettant de tester votre bibliothèque.

1) Un programme qui affiche "bonjour" précédé du numéro d'identification du processus et de son père.
2) Un programme qui se dédouble par l'appel fork et pour lequel les processus père et fils affichent respectivement "père" et "fils" précédés des mêmes informations que ci-dessus.
3) Que constatez vous lorsque vous exécutez plusieurs fois le programme de la question 2 ? Pour remédier à ce problème, écrivez un programme avec le même comportement que le précédent mais qui de plus garantit que le père attend la fin de l'exécution de son fils avant d'invoquer une fonction d'affichage.

II - Recouvrement

Écrire un source C qui se dédouble et pour lequel:

  1. le fils se recouvre par un nouveau processus qui exécute le programme de l'exercice I-B-1
  2. le père affiche 'Je suis le père' (via la bibliothèque de l'exercice I-A).

III - Lecture écriture de fichier et héritage des processus

Au cours du projet de l'unité IN3(ST)01, plusieurs processus seront amenés a s'échanger des messages à travers différents types de "fichier" (fichiers texte, tubes, entrés/sorties standards par exemple). Il est possible grâce aux appels systèmes read et write d'écrire et de lire de manière générique ces fichiers quels que soient leurs types. L'objectif de cet exercice est d'initier l'implémentation d'une bibliothèque de lecture et écriture dans ces fichiers. La question A décrit le contenu de la bibliothèque et la question B décrit comment tester la bibliothèque.

Remarque importante : Utilisez l'appel système open pour ouvrir un fichier, close pour le fermer et read pour lire à l'intérieur. Avant toute manipulation de ces fonctions consultez leur documentation en tapant 'man 2 open', 'man 2 read', et 'man 2 close'.

A - Dans cette bibliothèque, vous écrirez pour l'instant une seule fonction prenant comme paramètre un descripteur de fichier et retournant :

- une chaîne de caractères correspondant à la premère ligne lue depuis le descripteur de fichier, si celle ci a une taille inférieure à une constante TAILLEBUF (que vous définirez dans la bibliothèque) ;
- le pointeur NULL, sinon indiquera une erreur.

De plus, vous veillerez à ce que la chaîne de caractères retournée soit bien formatée, c'est-à-dire qu'elle se termine par le caractère de fin de chaîne '\0'.

B - Dans quatre autres fichiers C distincts vous implémenterez quatre fonctions main permettant de tester votre bibliothèque.

1) Un programme qui ouvre le fichier donné ici et affiche (via la bibliothèque de l'exercice I-A) sa première ligne à l'écran.
2) Un programme qui se dédouble, puis pour lequel chacun des deux processus ouvre le fichier, y lit une ligne et ferme le fichier.
3) Un programme qui ouvre le fichier, se dédouble, puis pour lequel chacun des deux processus lit une ligne dans le fichier et le ferme.
4) Un programme réalisant les mêmes opérations qu'à la question 3 mais pour lequel l'utilisateur peut spécifier au lancement via la ligne de commande le nom du fichier texte dans lequel il faut lire. Pour cela, vous devez utiliser la syntaxe 'int main(int argc, char **argv)'.

C - La position de lecture dans un fichier est-elle toujours partagée, toujours commune entre un père et son fils ? Discutez entre vous des différents cas possibles ? Est-ce cohérent avec ce que vous avez vu en cours ? Modifiez l'exercice B-4 de telle sorte que le processus fils lise toujours la première ligne du fichier et le père la seconde.

IV - Questions de réflexion

Qu'affiche chacun des segments de programme suivants ? Quel est le nombre de processus créés dans chaque cas ? Cela n'est pas forcément la peine de les compiler pour répondre à ces questions



(a) 
for (i=1; i<=4; i++)
{
pid = fork();
if (pid != 0) printf("%d\n", pid);
}

(b)
for (i=1; i<=4; i++)
{
pid = fork();
if (pid == 0) break;
else printf("%d\n", pid);
}

(c)
for (i=0; i<=nb; i++)
{
p = fork();
if (p < 0) exit(1);
execlp("prog", "prog",NULL);
}
wait(&status);

(d)
for (i=1; i<=nb; i++)
{
p1 = fork();
p2 = fork();
if (p1 < 0) exit(1);
if (p2 < 0) exit(1);
execlp("prog1", "prog1",NULL);
execlp("progc", "prog",NULL);
}
wait(&status);

Ce sujet a été élaboré par Jean COUSTY et Laurent NAJMAN
Laboratoire d'Informatique Gaspard-Monge, Université Paris-Est - Département Informatique, ESIEE Paris