multiprocessing fork () vs spawn ()
Czytałem opis tych dwóch z dokumentu Python :
ikra
Proces nadrzędny uruchamia nowy proces interpretera języka Python. Proces potomny odziedziczy tylko te zasoby, które są niezbędne do uruchomienia metody run () obiektów procesu. W szczególności niepotrzebne deskryptory plików i uchwyty z procesu nadrzędnego nie zostaną odziedziczone. Rozpoczynanie procesu przy użyciu tej metody jest raczej powolne w porównaniu z używaniem fork lub forkserver. [Dostępne w systemach Unix i Windows. Wartość domyślna w systemie Windows i macOS.]
widelec
Proces nadrzędny używa os.fork () do rozwidlenia interpretera Pythona. Proces potomny, gdy się zaczyna, jest w rzeczywistości identyczny z procesem nadrzędnym. Wszystkie zasoby rodzica są dziedziczone przez proces potomny. Zauważ, że bezpieczne rozwidlanie procesu wielowątkowego jest problematyczne. [Dostępne tylko w systemie Unix. Wartość domyślna w systemie Unix.]
A moje pytanie brzmi:
- czy jest tak, że rozwidlenie jest znacznie szybsze, ponieważ nie próbuje zidentyfikować, które zasoby skopiować?
- czy jest tak, że skoro fork powiela wszystko, „marnuje” znacznie więcej zasobów w porównaniu do funkcji spawn ()?
Odpowiedzi
- czy jest tak, że rozwidlenie jest znacznie szybsze, ponieważ nie próbuje zidentyfikować, które zasoby skopiować?
Tak, to znacznie szybciej. Jądro może sklonować cały proces i kopiuje tylko zmodyfikowane strony pamięci jako całość . Nie jest konieczne podłączanie zasobów do nowego procesu i uruchamianie interpretera od zera.
- czy jest tak, że skoro fork powiela wszystko, „marnuje” znacznie więcej zasobów w porównaniu do funkcji spawn ()?
Rozwidlenie na nowoczesnych jądrach wykonuje tylko "kopiowanie przy zapisie" i wpływa tylko na strony pamięci, które faktycznie się zmieniają. Jedynym zastrzeżeniem jest to, że „zapis” obejmuje już tylko iterację po obiekcie w CPythonie. Dzieje się tak, ponieważ liczba odwołań dla obiektu jest zwiększana.
Jeśli masz długotrwałe procesy z wieloma małymi obiektami w użyciu, może to oznaczać, że marnujesz więcej pamięci niż przy spawn. Anegdotycznie przypominam sobie Facebooka, który twierdził, że zużycie pamięci zostało znacznie zmniejszone dzięki przełączeniu z „rozwidlenia” na „spawn” dla swoich procesów Pythona.