Provided by: manpages-ro-dev_4.27.0-1_all bug

NUME

       vfork - creează un proces copil și blochează părintele

BIBLIOTECA

       Biblioteca C standard (libc, -lc)

SINOPSIS

       #include <unistd.h>

       pid_t vfork(void);

   Cerințe pentru macrocomenzi de testare a caracteristicilor pentru glibc (consultați feature_test_macros(7)):

       vfork():
           Începând cu glibc 2.12:
               (_XOPEN_SOURCE >= 500) && ! (_POSIX_C_SOURCE >= 200809L)
                   || /* Începând cu  glibc 2.19: */ _DEFAULT_SOURCE
                   || /* glibc <= 2.19: */ _BSD_SOURCE
           Înainte de glibc 2.12:
               _BSD_SOURCE || _XOPEN_SOURCE >= 500

DESCRIERE

   Descrierea standard
       (Din  POSIX.1  )  Funcția vfork() are același efect ca și fork(2), cu excepția faptului că comportamentul
       este nedefinit dacă procesul creat de vfork() fie modifică alte date  decât  o  variabilă  de  tip  pid_t
       utilizată  pentru  a stoca valoarea de returnare de la vfork(), fie returnează din funcția în care a fost
       apelată vfork(), fie apelează orice altă funcție înainte de a apela cu succes  _exit(2)  sau  una  dintre
       funcțiile din familia exec(3).

   Descrierea Linux
       vfork(),  la fel ca fork(2), creează un proces-copil al procesului apelant. Pentru detalii și valoarea de
       returnare și erori, consultați fork(2).

       vfork() este un caz special de clone(2). Acesta este utilizat pentru a crea  procese  noi  fără  a  copia
       tabelele de pagini ale procesului părinte. Aceasta poate fi utilă în aplicațiile sensibile la performanță
       în care se creează un proces-copil care apoi emite imediat un execve(2).

       vfork()  diferă de fork(2) prin faptul că firul apelant este suspendat până când firul copil termină (fie
       în mod normal, prin apelarea _exit(2), fie în mod anormal, după  transmiterea  unui  semnal  fatal),  sau
       efectuează  un  apel  la  execve(2). Până în acel moment, copilul împarte toată memoria cu părintele său,
       inclusiv stiva. Copilul nu trebuie să se întoarcă din funcția curentă sau să  apeleze  exit(3)  (care  ar
       avea  ca  efect  apelarea  gestionarilor  de  ieșire stabiliți de procesul părinte și golirea tampoanelor
       stdio(3) ale părintelui), dar poate apela _exit(2).

       Ca și în cazul fork(2), procesul-copil creat de vfork() moștenește copii  ale  diferitelor  atribute  ale
       procesului  apelantului (de exemplu, descriptori de fișiere, dispoziții de semnal și directorul curent de
       lucru); apelul vfork() diferă doar în ceea ce privește tratarea spațiului de adrese virtuale, așa cum s-a
       descris mai sus.

       Semnalele trimise părintelui sosesc după ce copilul eliberează memoria părintelui (de  exemplu,  după  ce
       copilul termină sau apelează execve(2)).

   Descrierea istorică (veche)
       În  Linux,  fork(2)  este  implementat  folosind  pagini  copy-on-write,  astfel încât singura penalizare
       suferită de fork(2) este timpul și memoria necesare pentru a duplica tabelele de pagini ale părintelui și
       pentru a crea o structură de sarcini unică pentru copil.  Cu toate acestea, în vremurile  de  demult,  un
       fork(2) ar fi necesitat realizarea unei copii complete a spațiului de date al apelantului, adesea inutil,
       deoarece,  de  obicei,  imediat după aceea se realizează un exec(3). Astfel, pentru o mai mare eficiență,
       BSD a introdus apelul de sistem vfork(), care nu copia complet spațiul de adrese al  procesului  părinte,
       ci împrumuta memoria și firul de control al părintelui până la un apel la execve(2) sau până la o ieșire.
       Procesul  părinte  a  fost  suspendat  în  timp ce copilul folosea resursele sale. Utilizarea vfork() era
       complicată: de exemplu, pentru a nu modifica datele din procesul părinte,  era  necesar  să  se  cunoască
       variabilele care se aflau într-un registru.

VERSIUNI

       Cerințele  impuse  lui  vfork()  de  către standarde sunt mai slabe decât cele impuse lui fork(2), astfel
       încât o implementare în care cele două sunt sinonime este conformă. În special, programatorul nu se poate
       baza pe faptul că părintele rămâne blocat până când copilul fie se termină, fie apelează execve(2) și  nu
       se poate baza pe niciun comportament specific cu privire la memoria partajată.

       Unii  consideră că semantica lui vfork() este un defect arhitectural, iar pagina de manual 4.2BSD afirmă:
       „Acest apel de sistem va fi eliminat atunci când sunt implementate  mecanisme  adecvate  de  partajare  a
       sistemului.  Utilizatorii  nu ar trebui să depindă de semantica de partajare a memoriei a vfork deoarece,
       în acest caz, va fi sinonim cu fork.” Cu toate acestea, chiar dacă hardware-ul  modern  de  gestionare  a
       memoriei  a  redus  diferența de performanță dintre fork(2) și vfork(), există diverse motive pentru care
       Linux și alte sisteme au păstrat vfork():

       •  Unele aplicații cu performanțe critice necesită micul avantaj de performanță conferit de vfork().

       •  Funcția vfork() poate fi implementată pe sisteme care nu dispun de o unitate de gestionare a  memoriei
          (MMU),  dar  funcția  fork(2)  nu poate fi implementată pe astfel de sisteme. (POSIX.1-2008 a eliminat
          vfork() din standard; justificarea POSIX pentru funcția posix_spawn(3) menționează că această funcție,
          care oferă o funcționalitate echivalentă cu  fork(2)+  exec(3),  este  concepută  pentru  a  putea  fi
          implementată pe sisteme care nu dispun de o MMU).

       •  Pe  sistemele în care memoria este limitată, vfork() evită necesitatea de a angaja temporar memoria (a
          se vedea descrierea /proc/sys/vm/overcommit_memory în proc(5)) pentru a executa un program nou. (Acest
          lucru poate fi deosebit de benefic în cazul în care un proces părinte mare dorește să execute  un  mic
          program  ajutător  într-un proces copil). În schimb, utilizarea fork(2) în acest scenariu necesită fie
          angajarea unei cantități de memorie egală cu dimensiunea procesului părinte (în cazul în care este  în
          vigoare  supraangajarea  strictă), fie supraangajarea memoriei cu riscul ca un proces să fie întrerupt
          de oom-killer.

   Note Linux
       Gestionarii de bifurcare stabiliți utilizând pthread_atfork(3) nu sunt apelați  atunci  când  un  program
       multi-fir  care  utilizează  biblioteca  multi-fire  NPTL  apelează vfork(). În acest caz, gestionarii de
       bifurcări sunt apelați într-un program care utilizează  biblioteca  multi-fire  LinuxThreads.  Consultați
       pthreads(7) pentru o descriere a bibliotecilor de multi-fire Linux.

       Un apel la vfork() este echivalent cu un apel la clone(2) cu flags specificat ca:

            CLONE_VM | CLONE_VFORK | SIGCHLD

STANDARDE

       Niciunul.

ISTORIC

       4.3BSD; POSIX.1-2001 (dar marcat ca OBSOLET).  POSIX.1-2008 elimină specificația vfork().

       Apelul  de  sistem  vfork()  a  apărut  în 3.0BSD. În 4.4BSD a devenit sinonim cu fork(2), dar NetBSD l-a
       introdus  din  nou;  a  se  vedea  http://www.netbsd.org/Documentation/kernel/vfork.html  Linux,  a  fost
       echivalent  cu  fork(2)  până  la Linux 2.2.0-pre6 aproximativ. De la Linux 2.2.0-pre9 (pe i386, ceva mai
       târziu pe alte arhitecturi) este un apel de sistem independent. Suportul pentru acesta a fost adăugat  în
       glibc 2.0.112.

AVERTISMENTE

       Procesul-copil  trebuie să aibă grijă să nu modifice memoria în moduri neintenționate, deoarece astfel de
       modificări vor fi văzute de procesul părinte odată ce copilul termină sau  execută  un  alt  program.  În
       această privință, gestionarii de semnal pot fi deosebit de problematici: dacă un gestionar de semnal care
       este invocat în copilul lui vfork() modifică memoria, aceste modificări pot duce la o stare inconsecventă
       a  procesului  din  perspectiva procesului părinte (de exemplu, modificările de memorie ar fi vizibile în
       procesul părinte, dar modificările stării descriptorilor de fișiere deschise nu ar fi vizibile).

       Atunci când vfork() este apelat într-un proces cu mai multe fire de execuție,  numai  firul  de  execuție
       apelant  este suspendat până când copilul termină sau execută un nou program. Aceasta înseamnă că copilul
       împarte un spațiu de adrese cu alt cod care rulează. Acest lucru poate fi periculos dacă un  alt  fir  de
       execuție din procesul părinte își schimbă acreditările (utilizând setuid(2) sau similar), deoarece există
       acum două procese cu niveluri de privilegii diferite care rulează în același spațiu de adrese. Ca exemplu
       al pericolelor, să presupunem că un program cu mai multe fire de execuție care rulează ca root creează un
       copil  folosind  vfork().  După  vfork(),  un  fir  de execuție din procesul părinte scade procesul la un
       utilizator fără privilegii pentru a rula un cod de neîncredere (de exemplu, poate prin  intermediul  unui
       modul  deschis  cu  dlopen(3)).  În  acest caz, sunt posibile atacuri în care procesul părinte utilizează
       mmap(2) pentru a pune în memorie codul care va fi executat de procesul copil privilegiat.

ERORI

       Detaliile de gestionare a semnalelor sunt obscure și diferă de la un sistem la altul.  Pagina  de  manual
       BSD  afirmă:  „Pentru  a  evita o posibilă situație de blocaj, procesele care sunt copii în mijlocul unui
       vfork() nu primesc niciodată semnale SIGTTOU sau SIGTTIN; mai degrabă, sunt permise ieșirile sau  ioctls,
       iar încercările de intrare au ca rezultat o indicație de sfârșit de fișier.”

CONSULTAȚI ȘI

       clone(2), execve(2), _exit(2), fork(2), unshare(2), wait(2)

TRADUCERE

       Traducerea    în   limba   română   a   acestui   manual   a   fost   făcută   de   Remus-Gabriel   Chelu
       <remusgabriel.chelu@disroot.org>

       Această traducere este  documentație  gratuită;  citiți  Licența publică generală GNU Versiunea 3  sau  o
       versiune   ulterioară   cu  privire  la  condiții  privind  drepturile  de  autor.   NU  se  asumă  NICIO
       RESPONSABILITATE.

       Dacă găsiți erori în traducerea acestui manual, vă rugăm să  trimiteți  un  e-mail  la  translation-team-
       ro@lists.sourceforge.net.

Pagini de manual de Linux 6.9.1                    2 mai 2024                                           vfork(2)