TP 1 - Gestion de Processus
Ce TP porte sur la gestion des processus en programmation système sous Unix/Linux. Il permet de comprendre le fonctionnement de l’appel système fork(), la création de processus fils, la synchronisation avec wait(), ainsi que l’analyse des arborescences de processus. Le TP inclut également un exercice pratique de génération de la suite de Fibonacci dans un processus fils.
D'après le document TP 1 - Gestion de Processus
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Systèmes d’exploitation & Programmation Concurrente · DOCX · 10 pages · 2014
Ce TP porte sur la gestion des processus en programmation système sous Unix/Linux. Il permet de comprendre le fonctionnement de l’appel système fork(), la création de processus fils, la synchronisation avec wait(), ainsi que l’analyse des arborescences de processus. Le TP inclut également un exercice pratique de génération de la suite de Fibonacci dans un processus fils. Pour réaliser ce TP, il est nécessaire de disposer d’un environnement de développement C avec un compilateur gcc et un système Unix/Linux.
Objectifs
- Comprendre le comportement de l’appel fork() et les valeurs retournées dans le processus parent et fils.
- Écrire un programme C qui crée un processus fils et exécute un programme externe.
- Générer la suite de Fibonacci dans un processus fils avec passage d’arguments en ligne de commande.
- Analyser l’arborescence des processus créés par des appels fork() imbriqués et conditionnels.
- Identifier et éviter la création de processus orphelins et zombies.
- Étudier les différentes sorties possibles d’un programme concurrent avec plusieurs processus.
Prérequis et installation
- Connaissances de base en programmation C.
- Compréhension du modèle de processus Unix/Linux et des appels système fork(), wait(), execl().
- Environnement Unix/Linux avec gcc installé.
- Terminal pour compiler et exécuter les programmes.
Exercice 1 : Identification des valeurs de pid dans un programme fork()
Ce programme simple crée un processus fils avec fork() et affiche les valeurs de pid à quatre endroits (lignes A, B, C et D). L’objectif est de comprendre ce que retourne fork() dans chaque processus.
Procédure :
- Compiler et exécuter le programme donné.
- Observer les valeurs affichées aux lignes A, B, C et D.
- Comparer avec les valeurs attendues en supposant que le pid du parent est 2600 et celui du fils 2603.
Explication :
- Au point A, dans le processus fils, fork() retourne 0.
- Au point B, getpid() dans le fils retourne son propre pid (2603).
- Au point C, dans le parent, fork() retourne le pid du fils (2603).
- Au point D, getpid() dans le parent retourne son propre pid (2600).
Les deux processus continuent l’exécution après fork(), mais la valeur retournée par fork() permet de distinguer le parent (retour non nul) du fils (retour 0).
Exercice 2 : Génération de la suite de Fibonacci dans un processus fils
L’objectif est d’écrire un programme C qui crée un processus fils avec fork(), puis exécute un programme générant la suite de Fibonacci dans ce fils. Le nombre d’éléments de la suite est passé en argument en ligne de commande.
Étape 1 : Écrire le programme fibonacci.c
Ce programme affiche n nombres de la suite de Fibonacci, où n est passé en argument.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char * argv[] )
{
int a=0;
int b=1;
int c;
int n=atoi(argv[1]);
while(n>0)
{
printf("%d \n",a);
c=a+b;
a=b;
b=c;
n=n-1;
}
}
Étape 2 : Écrire le programme tp1ex2.c
Ce programme crée un processus fils avec fork(). Le fils exécute le programme fibonacci avec execl(). Le parent attend la fin du fils avec wait().
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char * argv[]) {
pid_t pid;
int n=atoi(argv[1]);
if(argc != 2)
{
printf("Error \n");
return;
}
if(n<0)
{
printf("Error:Negative Entry \n");
return;
}
switch(pid=fork()) {
case -1:
perror("fork error \n");
break;
case 0:
execl("/home/Nessrine/fibonacci","fibonacci",argv[1],NULL);
break;
default:
wait(NULL);
break;
}
}
Étape 3 : Compilation et exécution
gcc tp1ex2.c -o tp1ex2
gcc fibonacci.c -o fibonacci
./tp1ex2 10
Le résultat attendu est l’affichage des 10 premiers nombres de la suite de Fibonacci :
0
1
1
2
3
5
8
13
21
34
Exercice 3 : Analyse du nombre de processus créés par un programme avec fork() conditionnel
Le programme suivant :
#include <unistd.h>
int main ( void )
{
fork () && ( fork () || fork () );
sleep (2);
return 0;
}
Demande de déterminer combien de processus sont créés et leur arborescence.
Analyse :
- Le premier fork() est évalué. Si son retour est 0 (fils), la partie droite du && n’est pas évaluée.
- Si le retour est non nul (parent), la partie droite (fork() || fork()) est évaluée.
- Dans (fork() || fork()), le second fork() n’est évalué que si le premier retourne 0.
Conclusion : Le processus principal crée 3 autres processus au total, nommés F1, F2 et F3, avec l’arborescence :
- Processus Principal
- └─ F1
- └─ F2
- └─ F3 (fils de F2)
Exercice 4 : Arborescence et gestion des processus orphelins et zombies
Programme :
#include <unistd.h>
#include <stdio.h>
int main ( ) {
int i=0 ;
while (fork() !=0 && i<2)
i=i+1;
printf(" Processus %d termine avec i=%d \n", getpid(), i);
return 0;
}
1. Arborescence des processus
Les processus créés sont :
- Processus Principal (PP)
- F1 (i=0)
- F2 (i=1)
- F3 (i=2)
2. Valeurs de i affichées
- F1 affiche i=0
- F2 affiche i=1
- F3 affiche i=2
- PP affiche i=2
3. Risque de processus orphelins et zombies
Oui, il existe un risque :
- F2 peut terminer avant PP, devenant zombie.
- PP peut terminer avant F3, rendant F3 orphelin.
On peut vérifier cela en lançant la commande ps -la dans un autre terminal pendant l’exécution.
4. Modification pour éviter orphelins et zombies et obtenir une arborescence spécifique
Il faut ajouter un appel à wait() dans la boucle while pour que chaque processus père attende la terminaison de ses fils :
#include <unistd.h>
#include <stdio.h>
int main ( ) {
int i=0 ;
while (fork() >=0 && i<2){
i=i+1;
wait();
}
printf(" Processus %d termine avec i=%d \n", getpid(), i);
return 0;
}
Cette modification garantit que les processus fils sont correctement attendus, évitant ainsi la création de zombies ou orphelins. L’arborescence obtenue est celle souhaitée, avec un contrôle strict des processus.
Exercice 5 : Analyse des sorties possibles d’un programme concurrent
Ce dernier exercice étudie les différentes sorties possibles d’un programme C qui crée plusieurs processus et effectue des appels printf(). On suppose que tous les appels printf() sont immédiatement flushés vers stdout.
Partie I : Possibilité d’obtenir certaines combinaisons d’output
Pour les combinaisons suivantes, indiquer si elles peuvent apparaître :
- A. 513242 : Oui
- B. 324251 : Oui
- C. 534212 : Non
- D. 531422 : Oui
- E. 523142 : Oui
Partie II : Énumération des outputs possibles
Les sorties possibles du programme sont :
- Output 1 : 0123
- Output 2 : 0132
- Output 3 : 0312
- Output 4 : 3012
Commentaires
Aucun commentaire pour le moment. Posez la première question.