FSEA 2024-2025
Département d’Informatique L2
Cours de SE 1 Prof : Dr Bery
Travaux pratiques 5 : Les Processus sous Windows 11
Exercice I
Ce TP a pour objectif de vous familiariser avec la notion de processus en C. Vous allez
apprendre à créer de nouveaux processus, à communiquer entre eux et à gérer leur cycle de
vie. Les concepts clés sont les suivants :
• Processus : Une instance d'un programme en cours d'exécution. Chaque processus
possède son propre espace mémoire, ses propres registres et un PID (Process
Identifier) unique.
• Fork : La fonction système qui permet de créer un nouveau processus, appelé fils, qui
est une copie quasi-conforme du processus père.
• PID : Le numéro d'identification unique d'un processus.
• État d'un processus : Un processus peut être dans différents états : en exécution, en
attente, terminé, etc.
NB : Il est plus aisé de faire ce TP sous Linux. Sous Windows, il faut installer des
bibliothèques.
Exercice 1 : Création d'un processus fils
Le programme suivant utilise fork() pour créer un nouveau processus. Le fils et le père
s'exécutent en parallèle, chacun affichant son PID et celui de son parent. Compiler et exécuter
plusieurs fois ce programme. Examiner les résultats obtenus. Avez-vous obtenu deux fois un
PID ?
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid < 0) {
perror("fork");
return 1;
} else if (pid == 0) {
// Processus fils
printf("Je suis le fils, mon PID est : %d, celui de mon père est :
%d\n", getpid(), getppid());
} else {
// Processus père
printf("Je suis le père, mon PID est : %d, celui de mon fils est :
%d\n", getpid(), pid);
}
return 0;
}
• Modifiez le programme pour que le processus fils attende 5 secondes avant de se
terminer.
• Compiler et exécuter et examiner les résultats obtenus
Exercice 2 : Communication entre processus avec des pipes
Dans le programme suivant, on utilise les pipes pour créer des canaux de communication
entre processus. Le père écrit un message dans le pipe, et les fils le lisent. Compiler et
exécuter plusieurs fois ce programme. Examiner les résultats obtenus.
#include <stdio.h>
#include <unistd.h>
int main() {
int fd[2];
pid_t pid1, pid2;
if (pipe(fd) == -1) {
perror("pipe");
return 1;
}
pid1 = fork();
if (pid1 < 0) {
perror("fork");
return 1;
} else if (pid1 == 0) {
// Fils 1
close(fd[1]);
char buffer[100];
read(fd[0], buffer, 100);
printf("Fils 1 : J'ai reçu : %s\n", buffer);
close(fd[0]);
} else {
pid2 = fork();
if (pid2 < 0) {
perror("fork");
return 1;
} else if (pid2 == 0) {
// Fils 2
close(fd[1]);
char buffer[100];
read(fd[0], buffer, 100);
printf("Fils 2 : J'ai reçu : %s\n", buffer);
close(fd[0]);
} else {
// Père
close(fd[0]);
write(fd[1], "Message pour les fils", 18);
close(fd[1]);
}
}
return 0;
}
• Modifiez le programme pour que les processus fils affichent leur PID
• Compiler et exécuter et examiner les résultats obtenus
Exercice 3 : Arbre de processus
La fonction create_process crée récursivement des processus pour construire l'arbre. Le
programme suivant qui crée un arbre de processus avec plusieurs niveaux. Chaque processus
fils crée à son tour deux processus fils. On utilise des PID pour identifier chaque processus et
afficher l'arbre de processus.
Compiler et exécuter plusieurs fois ce programme. Examiner les résultats obtenus
#include <stdio.h>
#include <unistd.h>
void create_process(int level) {
pid_t pid;
if (level == 0) {
return;
}
pid = fork();
if (pid < 0) {
perror("fork");
return;
} else if (pid == 0) {
// Processus fils
printf("Niveau %d, PID : %d\n", level, getpid());
create_process(level - 1);
}
}
int main() {
create_process(3); // Créer un arbre de 3 niveaux
return 0;
}
• Modifier la profondeur de l’arbre et examiner l’exécution du programme.
• Afficher cette arborescence avec un outil adéquate.
Exercice 4 : signal SIGINT
La fonction signal enregistre un gestionnaire pour le signal SIGINT. Lorsque ce signal est
reçu, la fonction handler est exécutée. Le programme suivnt capture le signal SIGINT
(Ctrl+C). Lorsque ce signal est reçu, le processus affiche un message et se termine
proprement. Examiner bien le code, le compiler et l’exécuter plusieurs fois. Examiner les
résultats obtenus.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handler(int sig) {
printf("Signal %d reçu\n", sig);
exit(0);
}
int main() {
signal(SIGINT, handler);
while (1) {
printf("En attente de signal...\n");
sleep(1);
}
return 0;}