Strony podręcznika są zwykle krótkimi dokumentami referencyjnymi. Wikipedia to lepsze miejsce, w którym można znaleźć wyjaśnienia pojęciowe.
Fork powiela proces: tworzy proces potomny, który jest prawie identyczny z procesem nadrzędnym (najbardziej oczywistą różnicą jest to, że nowy proces ma inny identyfikator procesu). W szczególności fork (koncepcyjnie) musi skopiować całą pamięć procesu nadrzędnego.
Ponieważ jest to dość kosztowne, vfork został wymyślony do obsługi typowego specjalnego przypadku, w którym kopiowanie nie jest konieczne. Często pierwszą rzeczą, którą robi proces potomny, jest załadowanie nowego obrazu programu, więc dzieje się tak:
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
Te execve
ładunki połączeń nowy program wykonywalny, a ta zastępuje proces za kod i dane pamięci przez kod nowego pliku wykonywalnego i świeżej pamięci danych. Tak więc cała utworzona przez nią kopia pamięci fork
była na nic.
W ten sposób vfork
wezwanie zostało wymyślone. Nie tworzy kopii pamięci. Dlatego vfork
jest tani, ale trudny w użyciu, ponieważ musisz upewnić się, że nie masz dostępu do żadnego stosu lub sterty procesu w procesie potomnym. Zauważ, że nawet czytanie może stanowić problem, ponieważ proces nadrzędny jest wykonywany. Na przykład ten kod jest uszkodzony (może, ale nie musi działać, w zależności od tego, czy dziecko lub rodzic najpierw otrzyma wycinek czasu):
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
Od czasu wynalezienia vfork wymyślono lepsze optymalizacje. Większość współczesnych systemów, w tym Linux, wykorzystuje formę kopiowania przy zapisie , w której strony w pamięci procesu nie są kopiowane w momencie fork
wywołania, ale później, gdy rodzic lub dziecko po raz pierwszy pisze na stronie. Oznacza to, że każda strona zaczyna się jako udostępniona i pozostaje udostępniona, dopóki którykolwiek z procesów nie zapisze na tej stronie; proces, który pisze, otrzymuje nową stronę fizyczną (z tym samym adresem wirtualnym). Kopiowanie przy zapisie sprawia, że vfork jest w większości bezużyteczny, ponieważ fork
nie tworzy żadnej kopii w przypadkach, w których vfork
byłby użyteczny.
Linux zachowuje vfork. fork
Wywołanie systemowe muszą jeszcze zrobić kopię wirtualnym stole pamięci procesu, nawet jeśli nie kopiować rzeczywistą pamięć; vfork
nawet nie musi tego robić. Poprawa wydajności jest znikoma w większości aplikacji.
fork
musi utworzyć osobne odwzorowanie pamięci wirtualnej, aby kolejne kopie kopiowania przy zapisie wpływały tylko na jeden z dwóch procesów.fork()
Ivfork()
syscalli są różne.fork()
Syscall generuje dwa identyczne procesów z oddzielnej pamięci.vfork()
Syscall generuje dwa procesy, które dzielą tę samą pamięć.Z
vfork()
rodzicem będzie czekać na zakończenie dziecka. Element nadrzędny dziedziczy po zmiennych współużytkowanych przez program. Tak więc po wywołaniu dziecka wszystkie zmienne zmodyfikowane wewnątrz dziecka będą nadal modyfikowane wewnątrz rodzica.Aby uzyskać więcej informacji, kliknij tutaj
źródło