vfork(2) System Calls Manual vfork(2) NUME vfork - creeaza un proces copil i blocheaza parintele BIBLIOTECA Biblioteca C standard (libc, -lc) SINOPSIS #include pid_t vfork(void); Cerine pentru macrocomenzi de testare a caracteristicilor pentru glibc (consultai feature_test_macros(7)): vfork(): Incepand cu glibc 2.12: (_XOPEN_SOURCE >= 500) && ! (_POSIX_C_SOURCE >= 200809L) || /* Incepand cu glibc 2.19: */ _DEFAULT_SOURCE || /* glibc <= 2.19: */ _BSD_SOURCE Inainte de glibc 2.12: _BSD_SOURCE || _XOPEN_SOURCE >= 500 DESCRIERE Descrierea standard (Din POSIX.1 ) Funcia vfork() are acelai efect ca i fork(2), cu excepia faptului ca comportamentul este nedefinit daca procesul creat de vfork() fie modifica alte date decat o variabila de tip pid_t utilizata pentru a stoca valoarea de returnare de la vfork(), fie returneaza din funcia in care a fost apelata vfork(), fie apeleaza orice alta funcie inainte de a apela cu succes _exit(2) sau una dintre funciile din familia exec(3). Descrierea Linux vfork(), la fel ca fork(2), creeaza un proces-copil al procesului apelant. Pentru detalii i valoarea de returnare i erori, consultai fork(2). vfork() este un caz special de clone(2). Acesta este utilizat pentru a crea procese noi fara a copia tabelele de pagini ale procesului parinte. Aceasta poate fi utila in aplicaiile sensibile la performana in care se creeaza un proces-copil care apoi emite imediat un execve(2). vfork() difera de fork(2) prin faptul ca firul apelant este suspendat pana cand firul copil termina (fie in mod normal, prin apelarea _exit(2), fie in mod anormal, dupa transmiterea unui semnal fatal), sau efectueaza un apel la execve(2). Pana in acel moment, copilul imparte toata memoria cu parintele sau, inclusiv stiva. Copilul nu trebuie sa se intoarca din funcia curenta sau sa apeleze exit(3) (care ar avea ca efect apelarea gestionarilor de ieire stabilii de procesul parinte i golirea tampoanelor stdio(3) ale parintelui), dar poate apela _exit(2). Ca i in cazul fork(2), procesul-copil creat de vfork() motenete copii ale diferitelor atribute ale procesului apelantului (de exemplu, descriptori de fiiere, dispoziii de semnal i directorul curent de lucru); apelul vfork() difera doar in ceea ce privete tratarea spaiului de adrese virtuale, aa cum s-a descris mai sus. Semnalele trimise parintelui sosesc dupa ce copilul elibereaza memoria parintelui (de exemplu, dupa ce copilul termina sau apeleaza execve(2)). Descrierea istorica (veche) In Linux, fork(2) este implementat folosind pagini copy-on-write, astfel incat singura penalizare suferita de fork(2) este timpul i memoria necesare pentru a duplica tabelele de pagini ale parintelui i pentru a crea o structura de sarcini unica pentru copil. Cu toate acestea, in vremurile de demult, un fork(2) ar fi necesitat realizarea unei copii complete a spaiului de date al apelantului, adesea inutil, deoarece, de obicei, imediat dupa aceea se realizeaza un exec(3). Astfel, pentru o mai mare eficiena, BSD a introdus apelul de sistem vfork(), care nu copia complet spaiul de adrese al procesului parinte, ci imprumuta memoria i firul de control al parintelui pana la un apel la execve(2) sau pana la o ieire. Procesul parinte a fost suspendat in timp ce copilul folosea resursele sale. Utilizarea vfork() era complicata: de exemplu, pentru a nu modifica datele din procesul parinte, era necesar sa se cunoasca variabilele care se aflau intr-un registru. VERSIUNI Cerinele impuse lui vfork() de catre standarde sunt mai slabe decat cele impuse lui fork(2), astfel incat o implementare in care cele doua sunt sinonime este conforma. In special, programatorul nu se poate baza pe faptul ca parintele ramane blocat pana cand copilul fie se termina, fie apeleaza execve(2) i nu se poate baza pe niciun comportament specific cu privire la memoria partajata. Unii considera ca semantica lui vfork() este un defect arhitectural, iar pagina de manual 4.2BSD afirma: ,,Acest apel de sistem va fi eliminat atunci cand sunt implementate mecanisme adecvate de partajare a sistemului. Utilizatorii nu ar trebui sa depinda de semantica de partajare a memoriei a vfork deoarece, in acest caz, va fi sinonim cu fork." Cu toate acestea, chiar daca hardware-ul modern de gestionare a memoriei a redus diferena de performana dintre fork(2) i vfork(), exista diverse motive pentru care Linux i alte sisteme au pastrat vfork(): o Unele aplicaii cu performane critice necesita micul avantaj de performana conferit de vfork(). o Funcia vfork() poate fi implementata pe sisteme care nu dispun de o unitate de gestionare a memoriei (MMU), dar funcia fork(2) nu poate fi implementata pe astfel de sisteme. (POSIX.1-2008 a eliminat vfork() din standard; justificarea POSIX pentru funcia posix_spawn(3) menioneaza ca aceasta funcie, care ofera o funcionalitate echivalenta cu fork(2)+ exec(3), este conceputa pentru a putea fi implementata pe sisteme care nu dispun de o MMU). o Pe sistemele in care memoria este limitata, vfork() evita necesitatea de a angaja temporar memoria (a se vedea descrierea /proc/sys/vm/overcommit_memory in proc(5)) pentru a executa un program nou. (Acest lucru poate fi deosebit de benefic in cazul in care un proces parinte mare dorete sa execute un mic program ajutator intr-un proces copil). In schimb, utilizarea fork(2) in acest scenariu necesita fie angajarea unei cantitai de memorie egala cu dimensiunea procesului parinte (in cazul in care este in vigoare supraangajarea stricta), fie supraangajarea memoriei cu riscul ca un proces sa fie intrerupt de oom-killer. Note Linux Gestionarii de bifurcare stabilii utilizand pthread_atfork(3) nu sunt apelai atunci cand un program multi-fir care utilizeaza biblioteca multi-fire NPTL apeleaza vfork(). In acest caz, gestionarii de bifurcari sunt apelai intr-un program care utilizeaza biblioteca multi-fire LinuxThreads. Consultai 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 elimina specificaia vfork(). Apelul de sistem vfork() a aparut in 3.0BSD. In 4.4BSD a devenit sinonim cu fork(2), dar NetBSD l-a introdus din nou; a se vedea Linux, a fost echivalent cu fork(2) pana la Linux 2.2.0-pre6 aproximativ. De la Linux 2.2.0-pre9 (pe i386, ceva mai tarziu pe alte arhitecturi) este un apel de sistem independent. Suportul pentru acesta a fost adaugat in glibc 2.0.112. AVERTISMENTE Procesul-copil trebuie sa aiba grija sa nu modifice memoria in moduri neintenionate, deoarece astfel de modificari vor fi vazute de procesul parinte odata ce copilul termina sau executa un alt program. In aceasta privina, gestionarii de semnal pot fi deosebit de problematici: daca un gestionar de semnal care este invocat in copilul lui vfork() modifica memoria, aceste modificari pot duce la o stare inconsecventa a procesului din perspectiva procesului parinte (de exemplu, modificarile de memorie ar fi vizibile in procesul parinte, dar modificarile starii descriptorilor de fiiere deschise nu ar fi vizibile). Atunci cand vfork() este apelat intr-un proces cu mai multe fire de execuie, numai firul de execuie apelant este suspendat pana cand copilul termina sau executa un nou program. Aceasta inseamna ca copilul imparte un spaiu de adrese cu alt cod care ruleaza. Acest lucru poate fi periculos daca un alt fir de execuie din procesul parinte ii schimba acreditarile (utilizand setuid(2) sau similar), deoarece exista acum doua procese cu niveluri de privilegii diferite care ruleaza in acelai spaiu de adrese. Ca exemplu al pericolelor, sa presupunem ca un program cu mai multe fire de execuie care ruleaza ca root creeaza un copil folosind vfork(). Dupa vfork(), un fir de execuie din procesul parinte scade procesul la un utilizator fara privilegii pentru a rula un cod de neincredere (de exemplu, poate prin intermediul unui modul deschis cu dlopen(3)). In acest caz, sunt posibile atacuri in care procesul parinte utilizeaza mmap(2) pentru a pune in memorie codul care va fi executat de procesul copil privilegiat. ERORI Detaliile de gestionare a semnalelor sunt obscure i difera de la un sistem la altul. Pagina de manual BSD afirma: ,,Pentru a evita o posibila situaie de blocaj, procesele care sunt copii in mijlocul unui vfork() nu primesc niciodata semnale SIGTTOU sau SIGTTIN; mai degraba, sunt permise ieirile sau ioctls, iar incercarile de intrare au ca rezultat o indicaie de sfarit de fiier." CONSULTAI I clone(2), execve(2), _exit(2), fork(2), unshare(2), wait(2) TRADUCERE Traducerea in limba romana a acestui manual a fost facuta de Remus- Gabriel Chelu Aceasta traducere este documentaie gratuita; citii Licena publica generala GNU Versiunea 3 sau o versiune ulterioara cu privire la condiii privind drepturile de autor. NU se asuma NICIO RESPONSABILITATE. Daca gasii erori in traducerea acestui manual, va rugam sa trimitei un e-mail la . Pagini de manual de Linux 6.9.1 2 mai 2024 vfork(2)