2011-01-17 19 views
29

Jakie są dobre wskazówki do zastosowania przy podejmowaniu decyzji o użyciu wątków lub procesach wieloprocesorowych, jeśli chodzi o wydajność i klarowność kodu?Python: Kiedy używać wątków a wieloprocesowość

+5

Zapomniałeś "w pętli zdarzeń". –

+2

Każda dobra odpowiedź musi wspomnieć o efektach ubocznych ze względu na globalną blokadę tłumacza podczas korzystania z wątków. –

+0

@Mike DeSimone - zgadzam się! :) – Russ

Odpowiedz

16

Wiele różnic między wątkami a procesami wieloprocesowymi nie jest specyficznych dla Pythona, a niektóre różnice dotyczą konkretnej implementacji w języku Python.

Dla CPython, chciałbym użyć modułu multiprocessing albo fo w następujących przypadkach:

  • muszę skorzystać z wielu rdzeni jednocześnie ze względu na wydajność. Globalna blokada interpretera (GIL) uniemożliwiłaby jakiekolwiek przyspieszenie podczas używania wątków. (Czasami możesz uciec w tym przypadku z wątkami, na przykład, gdy główna praca jest wykonywana w kodzie C, wywoływanym przez ctypes lub podczas używania Cythona i jawnego uwalniania GIL tam, gdzie jest to konieczne, oczywiście to drugie wymaga szczególnej ostrożności.) Zauważ, że ten przypadek jest raczej rzadki. Większość aplikacji nie jest ograniczona do czasu procesora, a jeśli tak jest, zazwyczaj nie używa się Pythona.

  • Chcę zmienić aplikację w rzeczywistą aplikację rozproszoną później. Jest to o wiele łatwiejsze do zrobienia w przypadku aplikacji wieloprocesorowej.

  • Pomiędzy zadaniami do wykonania jest bardzo mało wspólnego stanu.

W prawie wszystkich innych okolicznościach używałbym nici. (Obejmuje to aplikacje GUI elastyczne.)

6

Dla kodu jasności, jeden z największych rzeczy jest, aby nauczyć się poznawać i kochać przedmiot Queue za rozmowę pomiędzy wątkami (lub procesów, w przypadku korzystania multiprocessing ... wieloprocesorowe ma its own Queue object). Kolejki znacznie ułatwiają i wydaje mi się, że umożliwiają znacznie czystszy kod.

miałem a look dla niektórych porządnych przykładów kolejce, a ten ma kilka świetnych przykładów, jak z nich korzystać i jak przydatne są (dokładnie tej samej logice obowiązującej dla kolejki wieloprocesorowej): http://effbot.org/librarybook/queue.htm

Dla wydajność, szczegóły i wynik nie mogą znacząco wpłynąć na większość ludzi, ale dla python < = 3.1 implementacja dla CPython ma kilka interesujących (i potencjalnie brutalnych) problemów z wydajnością na maszynach wielordzeniowych, o których możesz chcieć wiedzieć. Te problemy dotyczą the GIL. David Beazley zrobił na nim a video presentation i jest wartzdecydowanie warty oglądania. Więcej informacji: here, w tym dalsze informacje na temat znaczących ulepszeń na tym froncie w pythonie 3.2.

Zasadniczo, moje tanie podsumowanie problemu z wielordzeniowymi związanymi z GILem polega na tym, że jeśli spodziewasz się uzyskać pełne wykorzystanie procesora z CPython < = 2,7 przez użycie wielu wątków, nie zdziw się, jeśli wydajność nie jest duża lub nawet gorzej niż pojedynczy rdzeń. Ale jeśli twoje wątki robią wiązkę i/o (odczyt/zapis pliku, dostęp do bazy danych, odczyt/zapis gniazda, itp.), Możesz nawet nie zauważyć problemu.

Moduł wieloprocesowy pozwala całkowicie uniknąć tego potencjalnego problemu z GIL, tworząc interpreter python (i GIL) na procesor.

+1

Dla większości kodu Pythona, nie dostaniesz żadnego przyspieszenia z wielu wątków w Pythonie 3.x albo - po prostu nie będzie już wolniejszy. –

+0

@Sven: Nie sądzę, że można powiedzieć "większość kodu". To naprawdę zależy od kodu! tj: ile czasu spędza kod na oczekiwaniu na rzeczy nie-pytonowe, w którym to czasie kolejna nić pytona może nucić. Jeśli wykonujesz wiele operacji wejścia/wyjścia, pracujesz z GUI lub pracujesz z rozbudowanymi rozszerzeniami C procesora (zakładając, że wypuszczają GIL), nici mogą zrobić gigantyczną różnicę. W zależności od tego, z kim rozmawiasz, "większość kodu" obejmuje serwery internetowe, w którym to przypadku [wiele smaków jest połączonych z wielką przewagą] (http://nichol.as/benchmark-of-python-web-servers). – Russ

+0

Pochodzenie z równoległego pomijania liczb, używanie wątków do robienia rzeczy, podczas gdy inny wątek blokuje (jak w kodzie GUI), nie jest dokładnie tym, co nazywam [przyśpieszeniem] (http://en.wikipedia.org/wiki/Speedup) (I wspomniałem o tych przypadkach użycia w mojej odpowiedzi). I dlatego, że można uzyskać przyspieszenie dla ciężkich procesorów C rozszerzeń, ale to nie jest dokładnie to, co nazwałbym kodem Pythona :) Szczerze mówiąc, masz rację, mój komentarz nie był bardzo jasny. –

Powiązane problemy