« Fork (programmation) » : différence entre les versions

Un article de Wikipédia, l'encyclopédie libre.
Contenu supprimé Contenu ajouté
Fschwarzentruber (discuter | contributions)
Fschwarzentruber (discuter | contributions)
→‎Interactions entre processus : simplification blabla sur processus zombies
Ligne 18 : Ligne 18 :


== Interactions entre processus ==
== Interactions entre processus ==
Il est possible d’interagir entre processus de plusieurs manières différentes. Premièrement, on peut envoyer des '''signaux. '''En langage de commande ''kill <pid>'' permet de tuer le processus ayant pour pid ce que l'on entre dans la commande.
Il est possible d’interagir entre processus de plusieurs manières. Premièrement, on peut envoyer des '''signaux. '''En langage de commande ''kill <pid>'' permet de tuer le processus ayant pour pid ce que l'on entre dans la commande.


Il est possible de '''faire attendre un processus''' grâce à ''sleep(n)'' pour bloquer le processus pendant n secondes, ou en utilisant ''pause()'' qui bloque jusqu'à la réception d'un signal.
Il est possible de '''faire attendre un processus''' grâce à ''sleep(n)'' pour bloquer le processus pendant n secondes, ou en utilisant ''pause()'' qui bloque jusqu'à la réception d'un signal.


Pour mettre fin à un processus, on peut utiliser ''exit(etat)'' sachant que etat est un code de fin, par convention 0 si ok, code d'erreur sinon.
Pour mettre fin à un processus, on peut utiliser ''exit(etat)'' sachant que etat est un nombre entier qui est code de fin. Ce code de fin est par convention 0 si tout s'est bien passé. Sinon, il vaut un code d'erreur sinon.


Il peut être très pratique que '''le père attende la fin de l'un de ses fils''', pour ce faire on utilise ''pid_t wait(int *ptr_etat)'' qui donne comme valeur de retour le pid du fils qui a terminé, et le code de fin est stocké dans ptr_etat.
Il peut être très pratique que '''le père attende la fin de l'un de ses fils'''. Pour ce faire, on utilise ''pid_t wait(int *ptr_etat)'' qui donne comme valeur de retour le pid du fils qui a terminé, et le code de fin est stocké dans le [[Pointeur (programmation)|pointeur]] ptr_etat.


On peut également '''attendre la fin du fils grâce à son pid''' : ''pid_t waitpid(pid_t pid, int *ptr_etat, int options).''
On peut également '''attendre la fin du fils grâce à son pid''' : ''pid_t waitpid(pid_t pid, int *ptr_etat, int options).''


Un terme commun dans la partie « Système » de l'informatique est ce que l'on appelle les '''processus zombies'''. Cela arrive quand le processus est terminé mais que le père n'a pas attendu son fils, c'est-à-dire qu'il n'a pas fait d'appels à ''wait()''. C'est une situation qu'il convient d'éviter absolument car le processus ne peut plus s'exécuter mais consomme encore des ressources.
Parfois, un processus est terminé mais son père ne l'a pas attendu, c'est-à-dire qu'il n'a pas fait d'appels à ''wait()''. On parle alors de [[Processus zombie|processus zombies]] ou défunts. Les processus zombies sont à éviter absolument car ces derniers ne s'exécute plus mais consomme encore des ressources.


[[File:Processus zombie.png|thumb|Processus zombie]]
[[File:Processus zombie.png|thumb|Processus zombie]]

Version du 13 mai 2024 à 09:25

En informatique, la fonction fork fait partie des appels système standard d'UNIX (norme POSIX[1]). Cette fonction permet à un processus (un programme en cours d'exécution) de se copier. Le fork donne naissance à un nouveau processus qui est sa copie conforme, par exemple en vue de réaliser un second traitement parallèlement au premier. Un bon moyen de visualiser l'effet d'un fork sur un processus est d'imaginer une division cellulaire[réf. nécessaire].

Fonctionnement

L'appel système fork duplique le processus courant. Il existe une filiation dans les processus : le créateur d'un nouveau processus est appelé le père et le nouveau processus, le fils. La plupart des attributs système du père (par exemple les droits sur le système de fichier) sont transmis au fils, de la même manière que l'héritage. Au démarrage d'un système Unix, un seul processus existe (de numéro 1). Tous les autres processus qui peuvent exister au cours de la vie du système descendent de ce premier processus, appelé init, via des appels système comme fork[2], vfork[3], posix_spawn[4] ou d'autres moyens. Sur les premiers UNIX, seul l'appel système fork permet de créer de nouveaux processus[5],[6].

Valeur de retour

L'appel système fork fournit une valeur résultat qui est un nombre entier.

  • Dans le processus père, l'appel fork() renvoie l'identifiant de processus (PID pour Process IDentifier) du fils
  • Dans le processus fils, l'appel fork() renvoie 0
  • En cas d'erreur, l'appel fork() renvoie -1.

Afin d'obtenir le PID courant, il suffit de faire l'appel système getpid(). L'appel à getppid() renvoie le PPID (Parent Process IDentifier), c'est-à-dire le PID du père.

Interactions entre processus

Il est possible d’interagir entre processus de plusieurs manières. Premièrement, on peut envoyer des signaux. En langage de commande kill <pid> permet de tuer le processus ayant pour pid ce que l'on entre dans la commande.

Il est possible de faire attendre un processus grâce à sleep(n) pour bloquer le processus pendant n secondes, ou en utilisant pause() qui bloque jusqu'à la réception d'un signal.

Pour mettre fin à un processus, on peut utiliser exit(etat) sachant que etat est un nombre entier qui est code de fin. Ce code de fin est par convention 0 si tout s'est bien passé. Sinon, il vaut un code d'erreur sinon.

Il peut être très pratique que le père attende la fin de l'un de ses fils. Pour ce faire, on utilise pid_t wait(int *ptr_etat) qui donne comme valeur de retour le pid du fils qui a terminé, et le code de fin est stocké dans le pointeur ptr_etat.

On peut également attendre la fin du fils grâce à son pid : pid_t waitpid(pid_t pid, int *ptr_etat, int options).

Parfois, un processus est terminé mais son père ne l'a pas attendu, c'est-à-dire qu'il n'a pas fait d'appels à wait(). On parle alors de processus zombies ou défunts. Les processus zombies sont à éviter absolument car ces derniers ne s'exécute plus mais consomme encore des ressources.

Processus zombie

Utilisation et alternative

Chaque processus d'un fork possède son propre espace d'adressage, qu'il est coûteux de dupliquer, même avec des astuces comme le copie-sur-écriture. Il est parfois avantageux de remplacer les forks par des fils (processus légers) qui partagent le même espace mémoire… aux risques et périls du programmeur, cependant.

La fonction fork est largement utilisée dans les applications client-serveur avec plusieurs clients simultanés.

Notes et références

Articles connexes