table of contents
- trixie-backports 4.31.0-1~bpo13+1
- testing 4.32.4-1
- unstable 4.32.4-1
| 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¶
(From POSIX.1) The vfork() function has the same effect as fork(2), except that the behavior is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from the function in which vfork() was called, or calls any other function before successfully calling _exit(3) or one of the exec(3) family of functions.
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() differs from fork(2) in that the calling thread is suspended until the child terminates (either normally, by calling _exit(3), or abnormally, after delivery of a fatal signal), or it makes a call to execve(2). Until that point, the child shares all memory with its parent, including the stack. The child must not return from the current function or call exit(3) (which would have the effect of calling exit handlers established by the parent process and flushing the parent's stdio(3) buffers), but may call _exit(3).
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), fork(2), _Fork(3), unshare(2), wait(2), _exit(3)
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.
| 5. juni 2026 | Linux man-pages 6.20 |