fork(2) System Calls Manual fork(2)

fork - Créer un processus enfant

Bibliothèque C standard (libc, -lc)

#include <unistd.h>
pid_t fork(void);

fork() crée un nouveau processus en copiant le processus appelant. Le nouveau processus est appelé enfant (« child »). Le processus appelant est appelé parent.

Les processus parent et enfant fonctionnent dans des espaces mémoire séparés. Au moment du fork(), les deux espaces mémoire ont le même contenu. Les écritures en mémoire, les associations de fichier (mmap(2)) et les désassociations (munmap(2)) effectuées par un processus ne concernent pas l'autre.

Le processus enfant est une copie exacte du processus parent, sauf sur les points suivants :

Les attributs de processus de la liste précédente sont tous définis dans POSIX.1. Les processus parent et enfant diffèrent également par les propriétés spécifiques Linux suivantes :

Notez également les points suivants :

En cas de succès, le PID de l'enfant est renvoyé au parent, et 0 est renvoyé à l'enfant. En cas d'échec -1 est renvoyé au parent, aucun processus enfant n'est créé, et errno est positionné pour indiquer l'erreur.

Une limite imposée par le système du nombre de threads a été atteinte. Il existe un certain nombre de limites qui peuvent occasionner cette erreur :
  • La limite de ressource souple RLIMIT_NPROC (définie avec setrlimit(2)), qui limite le nombre de processus et de threads pour l'ID d'un utilisateur réel, a été atteinte ;
  • La limite du système du noyau du nombre de processus et de threads, /"proc/sys/kernel/threads-max, a été atteinte (voir proc(5)) ;
  • Le numéro maximal de PID, /proc/sys/kernel/pid_max, a été atteint (voir proc(5)) ;
  • Le nombre maximal de PID (pids.max) imposée par le contrôleur de « nombre de processus » cgroup (PID) a été atteinte.
L’appelant parent opère sous la politique d’ordonnancement SCHED_DEADLINE et n’a pas l’attribut reset-on-fork activé. Consultez sched(7).
fork() a échoué car le noyau n'a plus assez de mémoire.
Il y a eu une tentative de créer un processus enfant dans l'espace de noms d'un PID dont le processus « init » s'est terminé. Voir pid_namespaces(7).
fork() n'est pas géré sur cette plate-forme (par exemple sur du matériel sans unité de gestion mémoire).
L'appel système a été interrompu par un signal et va être redémarré (cela n'est visible qu'à l'occasion d'un trace()).

POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

Sous Linux, fork() est implémenté en utilisant une méthode de copie à l'écriture. Cela consiste à ne faire la véritable duplication d'une page mémoire que lorsqu'un processus en modifie une instance. Tant qu'aucun des deux processus n'écrit dans une page donnée, celle‐ci n'est pas vraiment dupliquée. Ainsi les seules pénalisations induites par fork() sont le temps et la mémoire nécessaires à la copie de la table des pages du parent ainsi que la création d'une structure unique de tâche pour l'enfant.

Depuis la glibc 2.3.3, plutôt que d'invoquer l'appel système fork() du noyau, l'enveloppe fork() de la glibc qui est fournie comme faisant partie de l'implémentation de threading NPTL invoque clone(2) avec des attributs qui fournissent le même effet que l'appel système traditionnel (un appel à fork() est équivalent à un appel à clone(2) avec flags valant exactement SIGCHLD). L'enveloppe de la glibc invoque tous les gestionnaires de fourche (« fork ») établis avec pthread_atfork(3).

Consultez pipe(2) et wait(2) pour plus d'exemples.

#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(void)
{
    pid_t pid;
    if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
        perror(
        exit(EXIT_FAILURE);
    }
    pid = fork();
    switch (pid) {
    case -1:
        perror("fork");
        exit(EXIT_FAILURE);
    case 0:
        puts("Child exiting.");
        exit(EXIT_SUCCESS);
    default:
        printf("L'enfant est le PID %jd\n", (intmax_t) pid);
        puts("Parent exiting.");
        exit(EXIT_SUCCESS);
    }
}

clone(2), execve(2), exit(2), setrlimit(2), unshare(2), vfork(2), wait(2), daemon(3), pthread_atfork(3), capabilities(7), credentials(7)

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.

5 février 2023 Pages du manuel de Linux 6.03