Chapitre 2 : Création/Manipulation des processus Ingénierie des Systèmes d’Expl

Chapitre 2 : Création/Manipulation des processus Ingénierie des Systèmes d’Exploitation 2021/2022 Pr HANIN Filière : ASEDS, INE1 Plan 2 Cours: Ingénierie Systèmes d’exploitation Chapitre 2: Création/Manipulationdes processus 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 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() { /* Partie de code A*/ fork(); /* Partie de code B */ } Pr. HANIN Chapitre 2: Création/Manipulation des processus 7 Fork() Processus appelant dit processus père: /* Partie de code A */ Suite du processus appelant dit processus père: /* Partie de code B */ Suite du processus hérité dit processus fils: /* Partie de code B */ Mort du processus fils Mort du processus père La fonction fork(): Parallélisme Soit le code suivant: Lors de l’exécution: int main() { /* Partie de code A*/ fork(); /* Partie de code B */ } Pr. HANIN Chapitre 2: Création/Manipulation des processus 8 Fork() Processus appelant dit processus père: /* Partie de code A */ Suite du processus appelant dit processus père: /* Partie de code B */ Suite du processus hérité dit processus fils: /* 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. 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() { /* Partie de code A*/ if(fork()==0) { /* Partie de code B */ } else { /* Partie de code C */ } } Pr. HANIN Chapitre 2: Création/Manipulation des processus 10 Fork() Processus appelant dit processus père: /* Partie de code A */ Suite du processus appelant dit processus père: /* Partie de code C */ Fork()==pid du fils (différent de 0) Suite du processus hérité dit processus fils: /* Partie de code B */ Fork()==0 Mort du processus fils Mort du processus père 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: int main() { /* Partie commune */ int n; n=0; if(fork()==0) { /* Partie: processus fils */ n=n+2; printf("n=%d",n); } else { /* Partie: processus père*/ n=n+1; printf("n=%d",n); } } Pr. HANIN Chapitre 2: Création/Manipulation des processus 12 Ce programme affichera soit: n=2 n=1 Si le processus fils s’exécute en premier. soit: n=1 n=2 Si le processus père s’exécute en premier. A aucun moment, il n’affichera 3, car n vaut 0 dans les deux processus après le fork. Puis les additions portent sur des variables différentes. Le +2 et le +1 portent sur des zones mémoires différentes. 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: int main() { int n=0; if(fork()==0) { printf("n=%d",n+2); }else { wait(NULL); printf("n=%d",n+1); } } Pr. HANIN Chapitre 2: Création/Manipulation des processus 13 Ce programme affichera forcément n=2 puis n=1, car la fonction wait() placée au début du processus père force ce processus à attendre la fin du processus fils. Le n+2 s’exécute alors en premier. Une fois l’affichage de n=2 réalisé, le fils meurt. Il provoque alors le déblocage de la fonction wait() au niveau du processus père. Le n+1 peut alors se réaliser et l’affichage de n=1 aussi. Bibliothèque: #include<sys/wait.h> La fonction wait() Pr. HANIN Chapitre 2: Création/Manipulation des processus 14 Soit le code suivant: un père et ses deux fils int main() { int n=0, pid1, pid2; pid1=fork(); if(pid1==0) { printf("n=%d",n+2); } else { pid2=fork(); if(pid2==0) { //le deuxième fils ne fait rien }else { wait(NULL); printf("n=%d",n+1); } } } Si le processus fils pid2 meurt avant le processus fils pid1, le père sera débloqué. Et donc, une autrefois, on ne peut pas déterminer si le père ou son fils pid1 qui sera exécuté le premier. D’où l’utilisation de la fonction: waitpid() 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() Pr. HANIN Chapitre 2: Création/Manipulation des processus 17 Soit le code suivant: int main() { int n=0, pid1, pid2; pid1=fork(); if(pid1==0) { printf("n=%d",n+2); } else { pid2=fork(); if(pid2==0) { //le deuxième fils ne fait rien }else { waitpid(pid1, NULL, 0); printf("n=%d",n+1); } } } Ce programme affichera forcément n=2 puis n=1, car la fonction waitpid(pid1, NULL, 0) placée au début du processus père force ce processus à attendre la fin du processus fils pid1, même si le processus fils pid2 meurt le premier. La fonction sleep() Pr. HANIN Chapitre 2: Création/Manipulation des processus 18 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(); uploads/Industriel/ chapitre-2-creation-manipulation-des-processus-aseds-pdf.pdf

  • 41
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager