[Będę powtarzać część mojej odpowiedzi od tutaj .]
Dlaczego po prostu nie ma polecenia, które tworzy nowy proces od zera? Czy nie jest absurdalne i nieefektywne kopiowanie takiego, który zostanie zastąpiony od razu?
W rzeczywistości prawdopodobnie nie byłoby to tak skuteczne z kilku powodów:
„Kopiuj”, wyprodukowany przez fork()
to trochę abstrakcji, ponieważ jądro wykorzystuje kopiowanie przy zapisie systemu ; wszystko, co naprawdę trzeba stworzyć, to wirtualna mapa pamięci. Jeśli kopia następnie natychmiast wywołuje exec()
, większość danych, które zostałyby skopiowane, gdyby zostały zmodyfikowane przez aktywność procesu, nigdy tak naprawdę nie musi być kopiowana / tworzona, ponieważ proces nie robi nic wymagającego jego użycia.
Różne znaczące aspekty procesu potomnego (np. Jego środowisko) nie muszą być indywidualnie duplikowane ani ustawiane w oparciu o złożoną analizę kontekstu itp. Po prostu zakłada się, że są takie same jak proces wywołujący, i jest to dość intuicyjny system, który znamy.
Aby wyjaśnić # 1 nieco dalej, pamięć, która jest „kopiowana”, ale nigdy później dostępna, nigdy nie jest tak naprawdę kopiowana, przynajmniej w większości przypadków. Wyjątkiem w tym kontekście może być rozwidlenie procesu, a następnie zakończenie procesu nadrzędnego przed zastąpieniem go przez dziecko exec()
. Mówię, że może, ponieważ duża część rodzica mogłaby być buforowana, jeśli jest wystarczająca ilość wolnej pamięci, i nie jestem pewien, w jakim stopniu zostanie to wykorzystane (co zależy od implementacji systemu operacyjnego).
Oczywiście, to nie sprawia, że używanie kopii jest bardziej wydajne niż używanie pustej tabliczki - z wyjątkiem tego, że „pusta tablica” nie jest dosłownie niczym i musi obejmować przydział. System może mieć ogólny pusty / nowy szablon procesu, który kopiuje w ten sam sposób 1, ale tak naprawdę nie zachowałby niczego w porównaniu z widelcem kopiowania przy zapisie. Więc # 1 pokazuje tylko, że użycie „nowego” pustego procesu nie byłoby bardziej wydajne.
Punkt 2 wyjaśnia, dlaczego korzystanie z widelca jest prawdopodobnie bardziej wydajne. Środowisko dziecka jest dziedziczone od jego rodzica, nawet jeśli jest to zupełnie inny plik wykonywalny. Na przykład, jeśli proces nadrzędny jest powłoką, a podrzędna przeglądarka internetowa, $HOME
jest nadal taka sama dla obu z nich, ale ponieważ oba mogą później to zmienić, muszą to być dwie osobne kopie. Ten w dziecku jest produkowany przez oryginał fork()
.
1. Strategia, która może nie ma większego sensu, ale chodzi mi o to, że tworzenie procesu wymaga więcej niż kopiowania jego obrazu do pamięci z dysku.