Ze strony podręcznika użytkownika vfork()
:
vfork () różni się od fork () tym, że rodzic jest zawieszony, dopóki dziecko nie wykona wywołania execve (2) lub _exit (2). Dziecko dzieli całą pamięć ze swoim rodzicem, w tym stos, dopóki funkcja execve () nie zostanie wydana przez dziecko. Dziecko nie może powrócić z bieżącej funkcji lub wywołać exit (), ale może wywołać _exit ().
Dlaczego dziecko powinno _exit()
zamiast dzwonić exit()
? Mam nadzieję, że dotyczy to zarówno vfork()
i fork()
.
c
system-calls
fork
exit
Sen
źródło
źródło
Odpowiedzi:
Jak widać wcześniej ,
vfork
proces potomny nie pozwala na dostęp do pamięci rodzica.exit
jest funkcją biblioteki C (dlatego często jest zapisywana jakoexit(3)
). Wykonuje różne zadania czyszczenia, takie jak opróżnianie i zamykanie strumieni C (pliki otwierane za pomocą funkcji zadeklarowanych wstdio.h
) oraz wykonywanie funkcji określonych przez użytkownika zarejestrowanych watexit
. Wszystkie te zadania obejmują czytanie i zapisywanie w pamięci procesu._exit
wychodzi bez czyszczenia. Jest to bezpośrednio wywołanie systemowe (dlatego jest napisane jako_exit(2)
), zwykle realizowane przez umieszczenie numeru wywołania systemowego w rejestrze procesora i wykonanie określonej instrukcji procesora (rozgałęzienie do obsługi wywołania systemowego). To nie musi mieć dostępu do pamięci procesu, więc można to bezpiecznie zrobić povfork
.Po
fork
tym nie ma takich ograniczeń: proces nadrzędny i podrzędny są teraz całkowicie autonomiczne.źródło
init
jest rozwidlany przez jądro).exit
wykonaj dodatkowe czyszczenie, takie jak wywoływanie funkcji zarejestrowanych przezatexit
to, aby uzyskać dostęp do danych poza skopiowaną częścią._exit
wykonuje syscall bezpośrednio bez żadnego czyszczenia poza jądrem.źródło
Masz wywołanie potomne _exit (), aby uniknąć opróżniania buforów stdio (lub innych) po zakończeniu procesu potomnego. Ponieważ proces potomny stanowi dokładną kopię procesu macierzystego, proces potomny nadal ma wszystko, co rodzic miał w „stdout” lub „stderr”, bufory z <stdio.h>. Możesz (i będzie, w nieodpowiednich momentach) uzyskać podwójne dane wyjściowe, wywołując exit (), jedno z procedur obsługi atexit procesu potomnego, a drugie od rodzica, gdy bufory w procesie nadrzędnym zapełniają się i są opróżniane.
Zdaję sobie sprawę, że powyższa odpowiedź koncentruje się na szczegółach stdio.h, ale ta idea prawdopodobnie przenosi się na inne buforowane operacje we / wy, tak jak wskazuje jedna z powyższych odpowiedzi.
źródło
exit()
: - wykonuje pewne zadania czyszczenia, takie jak zamykanie strumieni we / wy i wielu, a następnie wraca do jądra._exit()
: - bezpośrednio przychodzi do jądra (nie wykonuj żadnych zadań czyszczenia).fork()
: zarówno rodzic, jak i dziecko mają inną tabelę plików, więc zmiana dokonana przez dziecko nie wpływa na parametry środowiska rodzica i odwrotnie.vfork()
: zarówno rodzic, jak i dziecko używają tej samej tabeli plików, więc zmiana dokonana przez dziecko wpływa na parametry środowiska rodzica. np. jakaś zmiennavar=10
, teraz uruchamianavar++
przez dziecko, a następnie uruchamiana nadrzędna, można zobaczyć efekt równieżvar++
w danych wyjściowych nadrzędnych.Jak powiedziałem, jeśli używasz
exit()
wvfork()
wówczas wszystkie I / O jest już zamknięta. Tak więc, nawet jeśli rodzic działa poprawnie, nie można uzyskać prawidłowego wyniku, ponieważ wszystkie zmienne są opróżniane, a wszystkie strumienie zamykane.źródło