FORK(2) Linux Programmeurs Handleiding FORK(2)

fork - maak een kind-proces

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

fork() maakt een nieuw proces aan door het huidige proces te dupliceren. Het nieuwe proces wordt het kind-proces genoemd. Het huidige proces wordt het ouder proces genoemd.

Het kind-proces en het ouder-proces draaien in aparte geheugen ruimten. Tijdens de fork() hebben beide geheugen gebieden dezelfde inhoud. Schrijven naar geheugen, afbeelden (mmap(2)) en vrijgeven (munmap(2)) van bestanden door een van de processen beïnvloeden het andere niet.

Het kind-proces is een exact duplicaat van het ouder-proces behalve de volgende punten:

  • Het kind heeft zijn eigen unieke proces ID en dit PID komt niet overeen met enig ID van een van de bestaande proces groepen ( (setpgid(2)) of sessie.
  • Het ouder proces ID van het kind is hetzelfde als het proces ID van de ouder.
  • Het kind erft het slot op het geheugen niet van de ouder (mlock(2), mlockall(2)).
  • Gebruik van bronnen (getrusage(2)) en de CPU tijd tellers (times(2)) worden op nul gezet in het kind.
  • De verzameling van in afwachting zijnde signalen in kind is leeg (sigpending(2)).
  • Het kind erft geen seinpaal aanpassingen van zijn ouder (semop(2)).
  • Het kind erft geen geassocieerde dossier sloten van zijn ouder fcntl(2)). (Aan de andere kant erft het wel fnctl(2) de open bestandsindicator sloten en de flock(2) van zijn ouder.)
  • Het kind erft geen timers van zijn ouder (setitimer(2), alarm(2), timer_create(2)).
  • Het kind erft geen uitstaande asynchrone Invoer/Uitvoer operatie van zijn ouder (aio_read(3), aio_write(3)), noch erft het enige asynchrone Invoer/Uitvoer contexts van zijn ouder (zie io_setup(2)).

De proces attributen in de voorafgaande lijst zijn allemaal gespecificeerd in POSIX.1. De ouder en het kind verschillen op met betrekking tot de volgende Linux-specifieke proces attributen:

  • Het kind erft geen meldingen over verandering in mappen (dnotify) van zijn ouder (zie de beschrijving van F_NOTIFY in fcntl(2)).
  • De prctl(2) PR_SET_PDEATHSIG wordt teruggezet zodat het kind geen signaal ontvangt wanneer zijn ouder stopt.
  • De standaard waarde van de timer speling wordt gezet op de huidige waarde van de ouder. Zie de beschrijving van PR_SET_TIMERSLACK in prctl(2).
  • De geheugen indelingen die werden gemarkeerd met de madvise(2) MADV_DONTFORK vlag worden niet overgeërfd langs fork().
  • Geheugen in de adres gebieden die werden gemarkeerd met de madvise(2) MADV_WIPEONFORK vlag wordt met 0-gevuld in het kind na de fork(). (DeMADV_WIPEONFORK instelling blijft van kracht voor deze adres gebieden in het kind)
  • Het beëindiging signaal van het kind is altijd SIGCHLD (zie clone(2)).
  • De toegangsrechten bits van de poort gezet door ioperm(2) worden niet geërfd door het kind; het kind moet de benodigde bits zelf aan zetten met ioperm(2).

Let op de volgende punten:

  • Het kind-proces wordt gemaakt met een enkele thread\mdie die fork() aanriep. De complete virtuele adresruimte van de ouder wordt gekopieerd in het kind, inclusief de statussen van de seinpalen, de conditie variabelen, en andere pthread objecten; het gebruik van pthread_atfork(3) kan nuttig zijn tijdens het afhandelen van problemen die dit kunnen veroorzaken.
  • Na een fork() in een multithreaded programma, kan het kind zonder problemen asynchrone-signaal-veilige functies aanroepen (zie signal-safety(7)) totdat het moment dat execve(2) wordt aangeroepen.
  • Het kind erft kopieën van de verzameling open bestandsindicatoren van de ouder. Elke bestandsindicator in het kind wijst naar dezelfde open bestandsindicator (zie open(2)) als de daarmee overeenkomende bestandsindicator in de ouder. Dit betekent dat de twee open bestandsindicatoren dezelfde open bestandsstatus vlaggen delen, de bestandspositie en de signaal-gedreven Invoer/Uitvoer attributen (zie de beschrijving van F_SETOWN en F_SETSIG in fcntl(2)).
  • Het kind erft kopieën van de verzameling open bericht rij-indicatoren van de ouder (zie mq_overview(7)). Elke bestandsindicator in het kind wijst naar dezelfde open bericht rij-indicator als de daarmee overeenkomende bestandsindicator in de ouder. Dit betekent dat de twee bestandsindicatoren dezelfde vlaggen mq_flags) delen.
  • Het kind erft kopieën van de verzameling open map stromen van de ouder (zie opendir(3)). POSIX.1 schrijft dat de overeenkomende map stromen in de ouder en het kind dezelfde map stroom posities mogen delen; op Linux/glibc doen ze dit niet.

Bij succes wordt de PID van het kind-proces teruggegeven aan het ouder-proces en wordt 0 teruggegeven in het kind-proces. Bij falen wordt -1 teruggegeven aan het ouder-proces, er wordt geen kind-proces gemaakt, en errno wordt overeenkomstig gezet.

Een door het systeem bepaalde limiet op het aantal threads werd tegengekomen. Er zijn verschillende limieten die deze fout kunnen oproepen:
  • de RLIMIT_NPROC zachte bron limiet (ingesteld via setrlimit(2)), die het aantal processen en threads voor het echte gebruikers ID limiteert, werd bereikt;
  • de systeem-brede limiet van de kernel op het aantal processen en threads, /proc/sys/kernel/threads-max, werd bereikt (zie proc(5));
  • het maximaal aantal PID´s, /proc/sys/kernel/pid_max, werd bereikt (zie proc(5)); of
  • de PID limiet (pids.max) opgelegd door de cgroup "proces nummer" (PID´s) controller werd bereikt.
De aanroeper werkt onder het SCHED_DEADLINE agendabeheer beleid en heeft niet de reset-on-fork vlag gezet. Zie sched(7).
fork() faalde in het vrijmaken van de nodige kernel structuren omdat er te weinig geheugen was.
Een poging werd gedaan om een kind-proces aan te maken in de PID naamruimte wiens "init" proces werd beëindigd. Zie pid_namespaces(7).
fork() is niet ondersteund op dit platform (bij voorbeeld: hardware zonder een Memory-Management Unit).
De systeem aanroep werd onderbroken door een signaal en wordt geherstart. (Dit kan alleen geobserveerd worden tijdens een trace.)

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

Onder Linux is fork() geïmplementeerd door gebruik te maken van copy-on-write pagina´s, de enige straf die dit mee brengt is de benodigde tijd en hoeveelheid geheugen die nodig is om de pagina tabellen van de ouder te dupliceren, en om een unieke taak structuur in het kind te maken.

In plaats van het aanroepen van de kernel´ fork() systeem aanroep, roept vanaf versie 2.3.3 de glibc fork() omwikkel functie, die voorzien is als onderdeel van de NPTL threading implementatie, clone(2) aan met vlaggen die hetzelfde effect geven als de traditionele systeem aanroep. (Een aanroep van fork() is equivalent met de aanroep van clone(2) waarbij de flags gespecificeerd wordt als precies SIGCHLD.) De glibc functie roept enig vork afhandelaars aan die werden vastgesteld door pthread_atfork(3) te gebruiken.

Zie pipe(2) en wait(2).

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

Deze pagina is onderdeel van release 5.13 van het Linux man-pages-project. Een beschrijving van het project, informatie over het melden van bugs en de nieuwste versie van deze pagina zijn op https://www.kernel.org/doc/man-pages/ te vinden.

De Nederlandse vertaling van deze handleiding is geschreven door Jos Boersema <joshb@xs4all.nl>, Mario Blättermann <mario.blaettermann@gmail.com> en Luc Castermans <luc.castermans@gmail.com>

Deze vertaling is vrije documentatie; lees de GNU General Public License Version 3 of later over de Copyright-voorwaarden. Er is geen AANSPRAKELIJKHEID.

Indien U fouten in de vertaling van deze handleiding zou vinden, stuur een e-mail naar debian-l10n-dutch@lists.debian.org.

22 maart 2021 Linux