Système d'Exploitation - Travaux Dirigés n°3
” Création de processus : première approche ”
Notions vues dans ce TD : Utilisation des fonctions fork ( ) et exec ( ).
Prochain TD : Manipulation des tables internes du SGF d'Unix en ” C ” .
PS : Les parties correspondant à du travail à faire sont toutes en italiques ; le restant étant du complément au cours.
La fonction ” fork ( ) ”
Le but de cet exercice est de se familiariser avec le mécanisme de création des processus sur Unix. Pour cela nous utilisons la fonction ” fork ( ) ” de la façon suivante :
# include <unistd.h>
# include <stdio.h>
...
int pid;
pid = fork ( ) ;
if (pid == - 1)
{ /* code si échec : printf ( ” le fork ( ) a échoué \n ” ) */
if (pid == 0)
{ /* code correspondant à l'exécution du processus fils */ }
else
{ /* code correspondant à l'exécution du processus père */ }
...
Ecrire un programme ” C ” qui crée deux processus (un père et son fils). Chacun d'eux affichera à l'écran qui il est (” je suis le pere de PID : ?? ”, ” je suis le fils de PID : ?? et de pere de PID : ?? ”). Pour cela utiliser les fonctions ” getpid ( ) et getppid ( ) ” dont vous trouverez l'interface dans le manuel (” man ”).
La fonction ” fork ( ) ” dans une boucle
Pour mieux comprendre le fonctionnement de la fonction de création de processus (” fork ( ) ”) nous allons l'utiliser dans une boucle itérative.
Ecrire un programme en ” C ” qui fait appel à la fonction ” fork ( ) ” dans une boucle ” for (i=0; i<3; i++) ”. A l'intérieur de chaque itération le programme affichera les informations suivantes :
(i : valeur_de_i) je suis le processus : pid, mon pere est : ppid, retour : retour
où
” valeur_de_i ” est la valeur du compteur de la boucle
” pid ” est le PID du processus courant,
” ppid ” est le PID du processus père du processus courant,
” retour ” est la valeur du code retour de l'appel à la fonction ” fork ( ) ”.
Dessiner l'arbre des processus correspondant à l'exécution de ce programme.
La fonction ” execl ( ) ”
La fonction ” execl ( ) ” illustre le mécanisme complémentaire à celui de la création de processus implanté via la fonction ” fork ( ) ”, dont dispose UNIX. Le principe que nous allons voir ici revient à modifier le code du programme à exécuter pendant l'exécution du code en cours.
Ecrire un programme appelé ” bonjour ” dont le code affiche à l'écran la chaîne suivante : ” bonjour ”.
Ecrire et lancer le programme suivant qui fait appel au programme ” bonjour ” via la méthode ” execl ( ) ” :
#include <stdio.h>
#include <unistd.h>
int main ( ) {
printf (” preambule du bonjour\n ”);
execl (”./bonjour”,(char *) 0);
printf (” postambule du bonjour\n ”);
}
Qu'en concluez-vous ?
PS : L'appel à la fonction ” execl ” pourrait être fait de la façon suivante, sans rien changer quant au résultat :
" execl ("./bonjour", "/bonjour",0) "
La fonction ” execv ( ) ”
La fonction ” execv ( ) ” utilise la notation ” intensive ” des paramètres passés à l'appel du programme principal.
Ecrire un programme appelé ” necho ” qui affiche les paramètres passés en argument lors de son appel.
Ecrivez et exécuter le programme suivant qui appelle le programme ” necho ” avec la fonction ” execl ” :
#include <stdio.h>
#include <unistd.h>
char *argv[5] = { ”bonjour”, ”au revoir”, ”123”, ”3.14159” };
int main ( ) {
argv [4] = (char *) 0;
execl ("./necho", argv[0], argv[1], argv[2], argv[3], (char *) 0);
printf ("postambule du bonjour\n");
}
Remplacez l'appel à ” execl ” par un appel à ” execv ”, afin d'obtenir le même résultat. Analyser les résultats obtenus.