Académique Documents
Professionnel Documents
Culture Documents
Travaux Pratiques 3
Prototype en C :
#include<unistd.h>
Fonctionnement de fork() :
crée un nouveau processus (processus fils) par duplication du processus courant (processus
père).
copie les segments de données et de pile du processus père; le segment texte est partagé.
les « pid » du père et du fils sont différents.
le fils hérite en partie de l'environnement du père.
retourne un entier:
• en cas de succès:
0 dans le fils.
pid du fils dans le père.
• en cas d'échec
-1 dans le père.
le fils n'est pas créé.
Suite à un fork, les processus père et fils poursuivent l'exécution du même programme. La valeur
retournée par fork permet de distinguer entre le père et le fils.
1
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
switch(pid=fork())
{
case -1:
printf("erreur"); return -1;
case 0:
printf("je suis le fils, mon numéro est %d\n", getpid()); return 0;
default:
printf("je suis le père, le numéro de mon fils est %d\n",pid); return 0;
}
return 0;
}
Exécution
$gcc -o exfork exfork.c
$./exfork
Programme 2 : utilisation de la fonction system()
Il y a une façon de créer un sous-processus en Unix/Linux, en utilisant la commande system(), de la
bibliothèque standard de C <stdlib.h>. Comme arguments, elle reçoit le nom de la commande (et peut-
être une liste d'arguments) entre guillemets. Il faut retenir que system() n'est pas un appel système, mais
une fonction C. Ce qui rend l'utilisation de la fonction system() moins performante qu'un appel système
de création de processus.
Tapez le code suivant ensuite expliquer et analyser le résultat. Exécuter plus qu’une fois pour voir les
différents affichages. A partir des affichages dessiner l’arborescence créée.
#include <stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
int pid;
printf("Hello World \n");
2
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
pid = fork();
if (pid == 0) {printf ("je suis le fils mon pid est : %d, mon père est %d\n", getpid(), getppid());
system("ps") ;}
Else
{ printf("je suis le père, le numéro de mon fils est %d \n", pid);}
return 0;
}
#include <stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
int main()
{
int pid, i;
for(i=0;i<3;i++)
{
pid = fork();
if(pid == 0) printf("je suis le fils mon pid est : %d, mon pere est %d\n",getpid(),getppid());
else
{ if (pid>0) printf("je suis le pere, mon numero est %d le numéro de mon fils est %d
\n",getpid(), pid);
else printf("erreur");}
}
return 0;
}
3
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
Exécuter le même programme plus qu’une fois. Dessiner l’arborescence des processus créés et analyser
l’affichage et son changement d’une exécution à l’autre.
Programme 4 : utilisation de &&
#include <stdio.h>
#include<unistd.h> // fork()
#include<sys/types.h> //getpid()
#include<stdlib.h> // exit()
#include<sys/wait.h> // wait()
int main()
{
fork() && fork() && fork();
printf("num %d, pere %d\n", getpid(), getppid());
while(wait(0)>0);
return 0;
}
Programme 5 : utilisation de ||
#include <stdio.h>
#include<unistd.h> // fork()
#include<sys/types.h> //getpid()
#include<stdlib.h> // exit()
#include<sys/wait.h> // wait()
4
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
int main()
{
fork() || fork() || fork();
printf("num %d, pere %d\n", getpid(), getppid());
while(wait(0)>0);
return 0;
}
Résultat possible :
5
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
int main()
{
6
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
int pid, i;
for(i=0;i<3;i++)
{
pid = fork();
if(pid == 0) printf("je suis le fils mon pid est : %d, mon pere est
%d\n",getpid(),getppid());
else
{ if (pid>0) printf("je suis le pere, mon numero est %d le numéro de mon fils est %d
\n",getpid(), pid);
else printf("erreur"); while(wait(0)>0);}
}
return 0;
}
While(wait(0)>0) : permet de n’avoir aucun processus orphelin. Donc par rapport au résultat
précédents aucun père de numéro 1 n’apparaitra. Car tous les pères doivent attendre leurs fils.
Vous allez utiliser deux scénarios. Le premier sans exit(0) dans le fils et le second avec exit(0) dans le
fils. Exécutez les deux progarmmes et analyser les résultats en termes d’affichages et de l’arborescence
de processus créés.
#include <stdio.h>
7
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
#include<unistd.h> // fork()
#include<sys/types.h> //getpid()
#include<stdlib.h> // exit()
#include<sys/wait.h> // wait()
int main()
{
int i,j;
for(i=0;i<2;i++)
{
switch (fork())
{
case -1: printf("erreur");
case 0 : for(j=1;j<4;j++)
printf("je suis le processus num %d, mon affichage num %d. Mon pere est :
%d\n",getpid(),j, getppid());
default: ;
}
}
for(i=0;i<2;i++) wait(NULL);
return 0;
}
Résultat d’exécution :
Le père 8145 (votre prog) a créé deux fils 8146 et 8147. Et le fils 8146 a créé un fils
8148
#include <stdio.h>
#include<unistd.h> // fork()
#include<sys/types.h> //getpid()
#include<stdlib.h> // exit()
#include<sys/wait.h> // wait()
int main()
{
int i,j;
8
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
for(i=0;i<2;i++)
{
switch (fork())
{
case -1: printf("erreur");
case 0 : for(j=1;j<4;j++)
printf("je suis le processus num %d, mon affichage num %d. Mon pere est :
%d\n",getpid(),j, getppid());
exit(0);
default: ;
}
}
for(i=0;i<2;i++) wait(NULL); //le père attend tous ses fils avant de terminer
return 0;
}
Résultat :
Avec exit(0) aucun fils ne peut créer d’autres fils. Chacun des fils fait l’affichage et termine.
Donc avec exit(), seul le père qui est votre prog qui créé deux fils
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid, pid2;
int i;
pid =fork();
if(pid>0) {
printf("je suis le père\n");
pid2=fork();
if(pid2==0) {for (i=0;i<10;i++) printf("%d , ",i);} else while(wait(0)>0);
while(wait(0)>0); //printf("salut");
}
else
{ if (pid==0) { sleep(1); for (i=10;i<20;i++) printf("%d , ",i);}
9
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
else return -1;}
return 0;
}
Travail à faire
Exercice 1 :
int main() {
int v=0 ;
system(“ps –f”);
printf(“\n\n”); fork();
system(“ps -f”);
printf(“V=%d \n\n”,v);
return 0;
}
b- Afin de séparer ou de distinguer l’affichage du père à celui du fils, on propose la nouvelle version
du programme.
#include <stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<wait.h>
int main()
{
int v=0,pid;
system("ps -f");
printf("\n\n");
pid=fork();
if (pid > 0) {
wait(NULL);
printf("je suis le père\n");
system("ps -f");
printf("je suis le père, V=%d \n\n",v); }
Else
{if (pid ==0) {printf("je suis le fils\n");
system("ps -f");
printf("je suis le fils, V=%d \n\n",v); }
else printf("erreur de création du fils");}
return 0;
}
Dans le programme initial, en premier lieu il faut ajouter la valeur de retour de fork pour distinguer le tt
du père de celui du fils(pid=fork()). Ceci n’est pas suffisant car il est possible qu’une instruction du bloc
d’instructions du père (ou le fils) soit exécutée ensuite une de l’autre processus soit exécutée. Par
conséquent, on ne pourra pas distinguer le résultat de ps-f du père à celui du fils. Donc, en plus des
messages qu’on ajoute pour préciser si c’est le père ou le fils, il faut ajouter le wait. Ceci, va obliger le
père de ne pas suivre son exécution que si son fils termine. Wait(NULL) : le père attend la fin d’exécution
de son fils pour qu’il puisse suivre son exécution. Faites attention, le changement de l’emplacement de
wait change tout. Donc, wait doit absolument être dans l’endroit où elle est placée dans la nouvelle
version. N’oubliez pas d’ajouter l’entête wait.h. Cette proposition, garantis la séparation demandée pour
11
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
n’importe qu’elle exécution. Ci-dessous, un résultat d’exécution.
je suis le fils
UID PID PPID C STIME TTY TIME CMD
runner16 7797 0 0 15:37 pts/1 00:00:00 sh -c ./a.out
runner16 7802 7797 0 15:37 pts/1 00:00:00 ./a.out
runner16 7805 7802 0 15:37 pts/1 00:00:00 ./a.out
runner16 7806 7805 0 15:37 pts/1 00:00:00 sh -c ps -f
runner16 7807 7806 0 15:37 pts/1 00:00:00 ps -f
je suis le fils, V=0
je suis le père
UID PID PPID C STIME TTY TIME CMD
runner16 7797 0 0 15:37 pts/1 00:00:00 sh -c ./a.out
runner16 7802 7797 0 15:37 pts/1 00:00:00 ./a.out
runner16 7808 7802 0 15:37 pts/1 00:00:00 sh -c ps -f
runner16 7809 7808 0 15:37 pts/1 00:00:00 ps -f
je suis le père, V=0
d. On doit affecter à v la valeur 1 dans la section du père et lui affecter la valeur 2 dans celle du fils.
#include <stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<wait.h>
int main()
{
int v,pid;
system("ps -f");
printf("\n\n");
pid=fork();
if (pid > 0) {wait(NULL);printf("je suis le père\n");
system("ps -f");
v=1;
printf("je suis le père, V=%d \n\n",v); }
else
{if (pid ==0) {
sleep(2);
printf("je suis le fils\n");
system("ps -f");
v=2;
12
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
printf("je suis le fils, V=%d \n\n",v); }
else printf("erreur de création du fils");}
return 0;
}
Exercice 2 :
Ecrivez les programmes en C permettant de créer des processus selon les figures suivantes :
a-
P1 P2 P3
rép :
fork()&&fork()&&fork()
P1 P2 P3
P21 P31
Rép :
fork()&&(fork()||fork())&&(fork()||fork())
c-
P1 P2 P3
13
Exercice 3 :
Ecrire un programme qui crée n processus fils. Avec n est passée en paramètre.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int
main (int argc, char **argv) // pour le passage en paramètre
{
int i;
pid_t pid;
if (argc > 1) //faites cette vérification pour être sûr que vous avez saisi un argument (le nombre n)
{
for (i = 0; i < atoi (argv[1]); i++) //atoi(argv[1] : te donne la valeur du premier arg
{
pid = fork ();
if (pid == 0)
{
Printf ("Je suis le fils mon numéro est %d , mon père est %d\n", getpid (), getppid ());
exit (0);
14
UNIVERSITE DE CARTHAGE DEPARTEMENT
FACULTE DES SCIENCES DE BIZERTE INFORMATIQUE
}
else
}
while (wait (0) > 0); //Ecrivez cette insctruction pour que le père attend tous ses fils
}
return 0;
15