| vfork(2) | System Calls Manual | vfork(2) |
NAVN¶
vfork - opret en underproces og bloker overproces
BIBLIOTEK¶
C-standardbibliotek (libc, -lc)
SYNOPSIS¶
#include <unistd.h>
pid_t vfork(void);
vfork():
Siden glibc 2.12:
(_XOPEN_SOURCE >= 500) && ! (_POSIX_C_SOURCE >= 200809L)
|| /* Siden 2.19: */ _DEFAULT_SOURCE
|| /* glibc <= 2.19: */ _BSD_SOURCE
Før glibc 2.12:
_BSD_SOURCE || _XOPEN_SOURCE >= 500
BESKRIVELSE¶
Standardbeskrivelse¶
(Fra POSIX.1) har funktionen vfork() den samme effekt som fork(2), med den undtagelse at opførelsen ikke er defineret hvis processen oprettet af vfork() enten ændrer data udover en variabel af typen pid_t brugt til at lagre returværdien fra vfork(), eller returnerer fra funktionen hvori vfork() blev kaldt eller kalder en anden funktion før _exit(2) kaldes med succes eller en af exec(3)-funktionsfamilien.
Linuxbeskrivelse¶
vfork(), ligesom fork(2), opretter en underproces af den kaldende proces. For detaljer og returværdi og fejl, se fork(2).
vfork() er et specielt tilfælde af clone(2). Bruges til at oprette nye processer uden at kopiere sidetabellen for overprocessen. Kan være nyttig i ydelsessensitive programmer, hvor en underproces er opretet, der øjeblikkeligt udsteder en execve(2).
vfork() er forskellig fra fork(2) ved at den kaldende tråd suspenderes indtil underprocessen afsluttes (enten normalt, ved at kalde _exit(2), eller unormalt, efter levering af et fatalt signal), eller den laver et kald til execve(2). Indtil det punkt deler underprocessen al hukommelse med sin overproces, inklusive stakken. Underprocessen må ikke returnere fra den nuværende funktion eller kalde exit(3) (hvilket ville have den effekt at kalde afslutningshåndteringer etableret af overprocessen og tømme overprocessens stdio(3)-mellemlagre, men må kalde _exit(2).
Som med fork(2), så arver underprocessen oprettet af vfork() kopier af forskellige af kalderens procesattributter (f.eks. fildeskriptorer, signaldispositioner og nuværende arbejdsmappe); Kaldet vfork() er kun anderledes i behandlingen af det virtuelle adresserum, som beskrevet ovenfor.
Signaler sendt til overprocessen ankommer efter at underprocessen frigiver overprocessens hukommelse (dvs. efter at underprocessen afslutter eller kalder execve(2)).
Historisk beskrivelse¶
Under Linux er fork(2) implementeret via copy-on-write-sider, så den eneste straf for fork(2) er tid og hukommelse krævet for at dublikere overprocessens sidetabeller, og oprette en unik opgavestruktur for underprocessen. I de dårlige gamle dage ville fork(2) ofte kræve en fuld kopi af kalderens datarum, ofte unødvendigt, da der normalt umiddelbart efter udføres en exec(3). For større effektivitet introducerede BSD systemkaldet vfork(), der ikke kopierer adresserummet for overprocessen fuldt ud, men låner overprocessens hukommelse og kontroltråd indtil et kald til execve(2) eller en afslut opstod. Overprocessen blev suspenderet mens underprocessen brugte sine ressourcer. Brug af vfork() var vanskelig: for eksempel gjorde det, at man ikke ændrede data i overprocessen, at man skulle kende til hvilke variabler, der var i et register.
VERSIONER¶
Kravene placeret på vfork() af standarderne er svagere end dem placeret på fork(2), så en implementering hvor de to er synonyme er kompatibel. Især kan programmøren ikke afhænge af at overprocessen forbliver blokeret indtil underprocessen enten afsluttes eller kalder execve(2), og kan ikke afhænge af en specifik opførelse med respekt for delt hukommelse.
Nogle anser semantikken for vfork() at være en arkitekturmæssig skamplet, og 4.2BSD-manualsiden sagde: “Dette systemkald vil blive elimineret når korrekte systemdelingsmekanismer er blevet implementeret. Brugere skal ikke afhænge af hukommelsesdelingssemantikken for vfork da den vil, i det tilfælde være synonym med fork.” Imidlertid, selv om moderne udstyr til hukommelseshåndtering er formindsket ydelsesforskellene mellem fork(2) og vfork(), er der forskellige årsager til hvorfor Linux og andre systemer har bevaret vfork():
- •
- Nogle ydelseskritiske programmer kræver den lille ydelsesfordel tildelt af vfork().
- •
- vfork() kan implementeres på systemer, der mangler en hukommelseshåndteringsenhed (MMU), men fork(2) kan ikke blive implementeret på sådanne systemer. (POSIX.1-2008 fjernede vfork() fra standarden; POSIX-rationalet for funktionen posix_spawn(3) bemærker, at den funktion, der tilbyder funktionalitet svarende til fork(2)+ exec(3), er designet til at kunne implementeres på systemer, der mangler en MMU).
- •
- På systemer hvor hukommelse er begrænset undgår vfork() behovet for midlertidigt at tildele hukommelse (se beskrivelsen af /proc/sys/vm/overcommit_memory i proc(5)) for at kunne afvikle et nyt program. (Dette kan være specielt gavnligt hvor en stor overproces ønsker at afvikle et lille hjælpeprogram i en underproces). Som kontrast, brug af fork(2) i dette scenarie kræver enten indsendelse af en stor mængde hukommelse svarende til størrelsen af overprocessen (hvis streng overforpligtelse er tvunget) eller overbelastning af hukommelse med risiko for at en proces bliver afsluttet af out-of-memory-dræberen (OOM).
Linux-noter¶
Forgreningshåndteirnger etableret under pthread_atfork(3) kaldes ikke, når et flertrådet program anvender NPTL-trådbibliotekskaldet vfork(). Forgreningshåndteringer kaldes i dette tilfælde i et program via LinuxThreads-trådbiblioteket. (Se pthreads(7) for en beskrivelse af Linux-trådbiblioteker).
Et kald til vfork() svarer til at kalde clone(2) med flag specificeret som:
CLONE_VM | CLONE_VFORK | SIGCHLD
STANDARDER¶
Ingen.
HISTORIK¶
4.3BSD; POSIX.1-2001 (men markeret FORÆLDET). POSIX.1-2008 fjerner specifikationen af vfork().
Systemkaldet vfork() dukkede op i 3.0BSD. I 4.4BSD blev det gjort synonymt med fork(2), men NetBSD introducerede det igen; se http://www.netbsd.org/Documentation/kernel/vfork.html. I Linux har det svaret til fork(2) indtil Linux 2.2.0-pre6 eller deromkring. Siden Linux 2.2.0-pre9 (på i386, lidt senere på andre arkitekturer) er det et uafhængigt systemkald. Understøttelse blev tilføjet i glibc 2.0.112.
FORBEHOLD¶
Underprocessen bør være omhyggelig med ikke at ændre hukommelsen på uønskede måder, da sådanne ændringer vil blive sendt til overprocessen, når underprocessen afsluttes eller afvikler et andet program. I disse tilfælde kan signalhåndteringer være specielt problematiske: hvis en signalhåndtering der igangsættes i underprocessen for vfork() ændrer hukommelsen, kan disse ændringer medføre en inkonsistent procestilstand fra overprocessens perspektiv (f.eks. hukommelsesændringer vil være synlige i overprocessen, men ændringer til tilstanden for åbne fildeskriptorer vil ikke være synlige.
Når vfork() kaldes i en flertrådet proces, så suspenderes kun den kaldende tråd indtil underprocessen afsluttes eller afvikler et nyt program. Dette betyder at underprocessen deler et adresesrum med anden afviklende kode. Dette kan være farligt hvis en anden tråd i overprocessen ændrer akkreditiver (via setuid(2) eller lignende), da der nu er to processer med forskellige privilegieniveauer kørende i det samme adresserum. Som et eksempel på farerne, antag at et flertrådet program, der afvikles som administrator opretter en underproces via vfork(). Efter vfork(), smider en tråd i overprocessen processen til en uprivilegeret bruger for at afvikle noget utroværdigt kode (f.eks. måske via udvidelsesmodul åbnet med dlopen(3)). I dette tilfælde er angreb muligt hvor overprocessen bruger mmap(2) til at indsætte kode, der vil blive afviklet af den privilegerede underproces.
FEJL¶
Detaljer for signalhåndteringen er obskure og forskellig mellem systemer. BSD-manualsiden siger: »For at undgå et muligt dødvande, så sendes processer, der er underprocesser i midten af en vfork() aldrig til SIGTTOU- eller SIGTTIN-signaler; resultat eller ioctl'er er derimod tilladt og inddataforsøg medfører en end-of-line-indikation«.
SE OGSŶ
clone(2), execve(2), _exit(2), fork(2), _Fork(3), unshare(2), wait(2)
OVERSÆTTELSE¶
Oversættere af denne manual til dansk Joe Hansen <joedalton2@yahoo.dk>
Denne oversættelse er gratis dokumentation; læs GNU General Public License version 3 eller nyere for ophavsretbetingelser. Der er INGEN ANSVAR.
Hvis du støder på fejl i oversættelsen af denne vejledning, skal du sende en besked til debian-l10n-danish@lists.debian.org.
| 8. februar 2026 | Linux man-pages 6.17 |