Debuguj wieloprocesowość w Pythonie

Odpowiedzi:

6

Prawdziwe wieloprzetwarzające programy w języku Python (w przeciwieństwie do wielowątkowych programów w języku Python, które mają do czynienia z przerażającym GIL ) nie różnią się od tych w żadnym innym języku. Wszystkie mają te same podstawowe wyzwania:

  1. Przydział zadań i raportowanie wyników. Nawet jeśli pracują głównie nad niezależnymi zestawami danych, zwykle muszą wrócić do głównego wątku, aby zgłosić wyniki i uzyskać nowe dane do pracy. Może to być uduszenie.
  2. Warunki wyścigu. Procesy próbują korzystać z jednego zasobu na raz i muszą używać muteksu (lub czegoś podobnego), aby nie przesadzać z danymi. Brak ochrony tego rodzaju zasobów może prowadzić do naprawdę bardzo bolesnych sesji debugowania.
  3. Sekwencyjność. Czasami próbujesz zrobić coś równoległego, co nie jest. Różne procesy w końcu czekają na siebie, aby coś zrobić, a końcowy rezultat jest taki, że we wszystkich zamiarach i celach wziąłeś program sekwencyjny, uczyniłeś go równoległym i nadal kończy się on na działaniu liniowym (lub gorzej).

Chociaż istnieją metody programistyczne, które starają się uniknąć każdego z tych problemów, na koniec dnia naprawdę musisz pomyśleć o tym, co robisz. Polecam ciężkie testy warunków skrajnych - znacznie wykraczające poza wszystko, co mogłoby się wydarzyć w prawdziwym życiu - abyś miał szansę na trafienie w te okna szansy i wysadzenie w fazie rozwoju, a nie w trakcie ważnego dema lub podczas produkcji.

Kiedyś używaliśmy plików dziennika z mikrosekundami, a następnie stworzyliśmy aplikację do przeglądania dziennika z kodowaniem kolorami, abyśmy mogli spróbować zobrazować, co się dzieje między procesem N uruchomionym na procesorach M. Próbowaliśmy także (i w większości udało się) stworzyć system, który odpędzałby pliki dziennika w celu odtworzenia kontekstu awarii.

Ale najlepszym narzędziem jest dobry projekt i naprawdę niegodziwi, paskudni ludzie, którzy próbują wysadzić twoją aplikację z wody. (Cześć, Dbell!)

Peter Rowell
źródło
26

Jedną z rzeczy, które uważam za bardzo pomocne, jest użycie istniejącego programu rejestrującego w multiprocessingmodule. Wypróbuj to w swoim głównym kodzie:

import multiprocessing, logging
mpl = multiprocessing.log_to_stderr()
mpl.setLevel(logging.INFO)

Zobacz także: http://docs.python.org/library/multiprocessing.html#logging

Ponadto można uzyskać dostęp do bieżącej nazwy procesu za pomocą:

cpname = multiprocessing.current_process().name
# print cpname
mylogger.info("{0} is currently doing...".format(cpname))

Zobacz: http://docs.python.org/library/multiprocessing.html#multiprocessing.current_process

Poza tym nie znam nic poza standardowymi metodami debugowania, takimi jak pdb& co.

ekshuma
źródło