Vous êtes sur la page 1sur 22

Ingénierie des Systèmes d’Exploitation

Chapitre 2 : Création/Manipulation des processus

Filière : ASEDS, INE1

Pr HANIN

2021/2022
Plan

 Chapitre 1 : Processus (Introduction générale)

 Chapitre 2 : Création / Manipulation des processus

 Chapitre 3 : Communication entre processus

 Chapitre 4: Ordonnancement des processus

 Chapitre 5: Gestion de la mémoire

 Chapitre 6: Gestion des entrées sorties et des fichiers

Cours: Ingénierie Systèmes d’exploitation


2
Plan

Chapitre 2: Création/Manipulation des processus

o La fonction getpid()

o La fonction getppid()

o La fonction fork()

o La fonction wait()

o La fonction waitpid()

o La fonction sleep()

o La fonction exit()

o Exercices

Pr. HANIN Chapitre 2: Création/Manipulation des processus 3


La fonction getpid()

Chaque processus s’exécutant sur un système est repéré par un numéro d’identification de type
entier. On l’appelle communément PID pour « Process Identification ».

En langage C: la fonction getpid() permet de retourner le PID du processus en cours.

Soit le programme suivant:

int main()
{ int d;
d=getpid();
printf("Le PID du processus qui exécute ce programme est: %d",d);
}

Ce programme affiche le PID du processus. Pour plusieurs exécutions de ce même programme le


résultat est différent.
Pr. HANIN Chapitre 2: Création/Manipulation des processus 4
La fonction getppid()

En langage C: la fonction getppid() permet de retourner le PID du processus père (c.-à-d. le PPID)
d’un processus donné.

Soit le programme suivant:

int main()

{ int d;

d=getppid();

printf("Le PPID du processus qui exécute ce programme est: %d",d);

Ce programme affiche le PPID du processus exécutant ce programme.

Pr. HANIN Chapitre 2: Création/Manipulation des processus 5


Les fonctions getpid() et getppid(): Exemple

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {

int pid, ppid; // pid_t pid,ppid;

pid=getpid();

ppid = getppid();

printf ("Le PID du processus courant est : %d\n", pid);

printf ("Le PID du processus parent est : %d\n", ppid);

Pr. HANIN Chapitre 2: Création/Manipulation des processus 6


La fonction fork(): Parallélisme
Cette fonction permet de créer un processus fils. Après la création du processus fils, l’exécution de la
suite code se dédouble. En effet, tout le code qui suit le fork, s’exécute aussi bien dans le processus
fils que dans le processus père.

Soit le code suivant: Lors de l’exécution:


int main()
Processus appelant dit processus père:
{ /* Partie de code A*/
/* Partie de code A */
fork();
/* Partie de code B */ Fork()
}

Suite du processus hérité Suite du processus appelant


dit processus fils: dit processus père:
/* Partie de code B */ /* Partie de code B */

Mort du processus fils


Mort du processus père
Pr. HANIN Chapitre 2: Création/Manipulation des processus 7
La fonction fork(): Parallélisme

Soit le code suivant: Lors de l’exécution:


int main()
Processus appelant dit processus père:
{ /* Partie de code A*/
/* Partie de code A */
fork();
/* Partie de code B */ Fork()
}

Suite du processus hérité Suite du processus appelant


dit processus fils: dit processus père:
/* Partie de code B */ /* Partie de code B */

Mort du processus fils


Mort du processus père

Remarque: Les deux processus se terminent lors de la fin de l’exécution de leurs codes respectifs.
Rien ne garantit que l’un ou l’autre se terminera avant. Tout dépend de l’ordonnancement des
processus au niveau système.

Pr. HANIN Chapitre 2: Création/Manipulation des processus 8


La fonction fork(): Parallélisme

Le code s’exécutant deux fois à partir de la fonction fork(), il est donc normal d’envisager que
cette fonction retourne une valeur pour chacun des deux processus. Il y a un résultat pour le
processus père, et un résultat pour le processus fils.

Par définition, la fonction fork() retourne:

 -1 si l’exécution a échoué (il faudra vérifier systématiquement le bon déroulement de la


fonction).

 0 pour le processus fils, si la fonction a réussi.

 Pid du fils pour le processus père, si la fonction a réussi.

On se sert donc de cette propriété pour différencier les codes pour les parties père et
fils.

Pr. HANIN Chapitre 2: Création/Manipulation des processus 9


La fonction fork(): Parallélisme

Soit le code suivant: Lors de l’exécution:


int main() Processus appelant dit
{ /* Partie de code A*/ processus père:
/* Partie de code A */
if(fork()==0)
{ Fork()
/* Partie de code B */
}
else Suite du processus hérité Suite du processus appelant
{ dit processus fils: dit processus père:
/* Partie de code B */ /* Partie de code C */
/* Partie de code C */ Fork()==0 Fork()==pid du fils (différent de 0)
}
} Mort du processus fils
Mort du processus père

Pr. HANIN Chapitre 2: Création/Manipulation des processus 10


La fonction fork(): Parallélisme

Notez bien que:

La fonction fork() provoque non seulement la naissance d’un nouveau processus, mais aussi la
duplication des zones mémoires. En effet, chaque processus a son propre espace de mémoire. À la
création du nouveau processus, les variables utilisées dans le processus père restent inchangées et
continuent leur évolution. Le processus fils bénéficie des mêmes variables et des mêmes valeurs,
mais dans des zones mémoires différentes.

Ces variables du fils évolueront différemment de celles du processus père. Ce sont des variables
distinctes. Elles ne sont pas partagées entre les différents processus (père et son fils).

Pr. HANIN Chapitre 2: Création/Manipulation des processus 11


La fonction fork(): Parallélisme
Soit le code suivant: Ce programme affichera soit:

int main() n=2

{ /* Partie commune */ n=1


int n; Si le processus fils s’exécute en premier.
n=0; soit:
if(fork()==0) n=1
{ /* Partie: processus fils */
n=2
n=n+2;
printf("n=%d",n); Si le processus père s’exécute en premier.
}
else A aucun moment, il n’affichera 3, car n vaut 0 dans
{ /* Partie: processus père*/ les deux processus après le fork. Puis les additions
n=n+1;
portent sur des variables différentes. Le +2 et le +1
printf("n=%d",n);
} portent sur des zones mémoires différentes.
}
Pr. HANIN Chapitre 2: Création/Manipulation des processus 12
La fonction wait()
Une première synchronisation est réalisée par l’intermédiaire de la fonction Celle-ci a pour effet
de bloquer l’exécution du processus en attendant la mort d’un de ses processus fils.

Soit le code suivant:


Ce programme affichera forcément n=2 puis n=1,
int main()
car la fonction wait() placée au début du processus
{
père force ce processus à attendre la fin du
int n=0;
if(fork()==0) processus fils.
{
Le n+2 s’exécute alors en premier. Une fois
printf("n=%d",n+2);
l’affichage de n=2 réalisé, le fils meurt. Il provoque
}else
alors le déblocage de la fonction wait() au niveau du
{
wait(NULL); processus père. Le n+1 peut alors se réaliser et
printf("n=%d",n+1); l’affichage de n=1 aussi.
}
}
Bibliothèque: #include<sys/wait.h>

Pr. HANIN Chapitre 2: Création/Manipulation des processus 13


La fonction wait()
Soit le code suivant: un père et ses deux fils
int main()
{ int n=0, pid1, pid2;
pid1=fork();

Si le processus fils pid2 meurt avant le processus


if(pid1==0)
{ printf("n=%d",n+2); fils pid1, le père sera débloqué. Et donc, une
} autrefois, on ne peut pas déterminer si le père ou son
else fils pid1 qui sera exécuté le premier.
{ pid2=fork();
if(pid2==0) D’où l’utilisation de la fonction: waitpid()

{ //le deuxième fils ne fait rien


}else
{ wait(NULL);
printf("n=%d",n+1);
}
}
}
Pr. HANIN Chapitre 2: Création/Manipulation des processus 14
La fonction waitpid()

La fonction wait() marche forcément du père vers le fils. Il ne faut pas aussi qu’il y ait des
ambiguïtés sur les processus qui meurent. En effet, si un processus génère deux fils (deux
fonctions fork). Une fonction wait() attendra la mort d’un des fils. Il est impossible de savoir
lequel des deux fils a débloqué le père. D’où l’utilisation de la fonction:

waitpid(pid_t pid, int *status, int options);

La fonction waitpid() suspend l’exécution du processus courant jusqu’à ce que le processus


fils numéro pid se termine.

Pr. HANIN Chapitre 2: Création/Manipulation des processus 15


La fonction waitpid()

waitpid(pid_t pid, int *status, int options);

La valeur de pid peut être l’une des suivantes:

 -1 attendre la fin de n’importe quel fils. C’est le même comportement que wait().

 PID du fils ( > 0 ) attendre la fin du processus fils numéro pid.

En cas de réussite, le PID du fils qui s’est terminé est renvoyé, en cas d’échec -1 est renvoyé.

Bibliothèque: #include <sys/wait.h>

Pr. HANIN Chapitre 2: Création/Manipulation des processus 16


La fonction waitpid()
Soit le code suivant:
int main()
{ int n=0, pid1, pid2;
pid1=fork(); Ce programme affichera forcément n=2 puis n=1,
car la fonction waitpid(pid1, NULL, 0) placée au
if(pid1==0)
début du processus père force ce processus à
{ printf("n=%d",n+2);
} attendre la fin du processus fils pid1, même si le

else processus fils pid2 meurt le premier.


{ pid2=fork();
if(pid2==0)
{ //le deuxième fils ne fait rien
}else
{ waitpid(pid1, NULL, 0);
printf("n=%d",n+1);
}
}
}
Pr. HANIN Chapitre 2: Création/Manipulation des processus 17
La fonction sleep()
int sleep(int n);

sleep suspend l’exécution du processus appelant pour une durée de n secondes.

Soit le code suivant:

int main()

{ int n, pid;
n=0;
pid=fork();

if(pid==0)
{ printf("n=%d",n+2);
}else
{ sleep(10);
printf("n=%d",n+1);
}
}
Pr. HANIN Chapitre 2: Création/Manipulation des processus 18
La fonction sleep()

Soit le code suivant: Exécuter ce programme, et visualiser l’état du processus fils à


travers l’utilisation de la commande ps.

int main()

{ int n, pid;
n=0;
pid=fork();
if(pid==0)
{ printf("n=%d",n+2);
}else
{ sleep(100);
printf("n=%d",n+1);
}
}

Pr. HANIN Chapitre 2: Création/Manipulation des processus 19


La fonction exit()
void exit(int n);

exit(n) met fin au processus courant avec le code de retour n (par convention, le code
de retour après un comportement correct est 0). Bibliothèque: #include <stdlib.h>

Soit le code suivant:

int main()

{ int pid;
pid=fork();
if(pid==0)
{ printf("Je suis le processus fils\n");
}else
{ exit(0);
printf("Je suis le processus père\n");
}
}

Pr. HANIN Chapitre 2: Création/Manipulation des processus 20


La fonction exit()

Soit le code suivant:

int main()

{ int pid;
pid=fork();

if(pid==0)
{ printf("Je suis le processus fils \n");
exit(0);
printf("Bonjour S2\n");
}else
{
printf("Je suis le processus père \n");
}
}

Pr. HANIN Chapitre 2: Création/Manipulation des processus 21


Les fonctions exit() et sleep()
Soit le code suivant: Exécuter ce programme, et visualiser l’état du processus fils à travers
l’utilisation de la commande ps.

int main()

{ int n=0, pid;

pid=fork();

if(pid==0){

printf("n=%d",n+2);

sleep(100);

}else{

exit(0);

printf("n=%d",n+1);
}
}
Pr. HANIN Chapitre 2: Création/Manipulation des processus 22

Vous aimerez peut-être aussi