multiprocessing fork () vs spawn ()

Sep 28 2020

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:

  1. czy jest tak, że rozwidlenie jest znacznie szybsze, ponieważ nie próbuje zidentyfikować, które zasoby skopiować?
  2. czy jest tak, że skoro fork powiela wszystko, „marnuje” znacznie więcej zasobów w porównaniu do funkcji spawn ()?

Odpowiedzi

3 Darkonaut Sep 28 2020 at 12:25
  1. 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.

  1. 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.