Wywołanie systemowe UNIX do tworzenia procesów, fork (), tworzy proces potomny poprzez skopiowanie procesu macierzystego. Rozumiem, że prawie zawsze następuje wywołanie exec () w celu zastąpienia przestrzeni pamięci procesu potomnego (w tym segmentu tekstowego). Kopiowanie przestrzeni pamięci rodzica w fork () zawsze wydawało mi się marnotrawstwem (chociaż zdaję sobie sprawę, że marnotrawstwo można zminimalizować poprzez kopiowanie segmentów pamięci przy zapisie, więc kopiowane są tylko wskaźniki). W każdym razie, czy ktoś wie, dlaczego takie podejście do powielania jest wymagane do tworzenia procesów?
process
process-management
fork
Ellen Spertus
źródło
źródło
fork(2)
strona podręcznika pod Linuksem mówi:Under Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child.
Wyobrażam sobie (ale nie jestem pewien), że tak jest w przypadku innych współczesnych smaków uniksowych.select
zostały zepsute, ale to już inna historia).Odpowiedzi:
Ma to na celu uproszczenie interfejsu. Alternatywą
fork
iexec
byłoby coś jak Windows' CreateProcess funkcji. Zauważ, ileCreateProcess
ma parametrów , a wiele z nich to struktury o jeszcze większej liczbie parametrów. Dzieje się tak, ponieważ wszystko , co możesz chcieć kontrolować nad nowym procesem, musi zostać przekazaneCreateProcess
. W rzeczywistościCreateProcess
nie ma wystarczających parametrów, więc Microsoft musiał dodać CreateProcessAsUser i CreateProcessWithLogonW .W
fork/exec
modelu nie potrzebujesz wszystkich tych parametrów. Zamiast tego niektóre atrybuty procesu są zachowywane w poprzekexec
. Umożliwiafork
to zmianę, a następnie zmianę dowolnych atrybutów procesu (przy użyciu tych samych funkcji, których normalnie używasz), a następnieexec
. W Linuksiefork
nie ma parametrów iexecve
ma tylko 3: program do uruchomienia, wiersz poleceń, aby go podać, i jego środowisko. (Istnieją inneexec
funkcje, ale są one tylko opakowaniamiexecve
dostarczonymi przez bibliotekę C w celu uproszczenia typowych przypadków użycia).Jeśli chcesz, aby rozpocząć proces z innego katalogu bieżącego:
fork
,chdir
,exec
.Jeśli chcesz przekierować stdin / stdout:
fork
blisko / Otwórz plikiexec
.Jeśli chcesz użytkowników przełączników:
fork
,setuid
,exec
.Wszystkie te rzeczy można łączyć w razie potrzeby. Jeśli ktoś wymyśli nowy rodzaj atrybutu procesu, nie musisz go zmieniać
fork
iexec
.Jak wspomniano w Larsku, większość współczesnych Uniksów używa kopiowania przy zapisie, więc
fork
nie wiąże się to z dużym nakładem pracy .źródło
Oprócz odpowiedzi cjm specyfikacja Single Unix definiuje funkcję o nazwie
vfork()
. Ta funkcja działa jak fork, z wyjątkiem tego, że rozwidlony proces ma niezdefiniowane zachowanie, jeśli robi coś innego niż próba wywołania funkcji exec rodzinnej lub wywołania_exit()
.Tak więc prawie jedynym zastosowaniem ze zdefiniowanym zachowaniem jest:
Co więc robi
vfork
? To jest taniefork
. W implementacjach bez kopiowania przy zapisie wynikowy proces będzie współdzielił przestrzeń pamięci z procesem oryginalnym (stąd niezdefiniowane zachowanie). W implementacjach z kopiowaniem przy zapisievfork
dozwolona jest identycznośćfork()
, ponieważ implementacje kopiowania przy zapisie są szybkie.Istnieje również
posix_spawn
funkcja opcjonalna (iposix_spawnp
funkcja), która może bezpośrednio utworzyć nowy proces. (Dozwolone jest również ich implementowanie za pomocą wywołania biblioteki przy użyciufork
iexec
oraz podano przykładową implementację).źródło