Czy istnieje klasa Pool dla wątków roboczych , podobna do klasy Pool modułu wieloprocesowego ?
Podoba mi się na przykład prosty sposób na zrównoleglenie funkcji mapy
def long_running_func(p):
c_func_no_gil(p)
p = multiprocessing.Pool(4)
xs = p.map(long_running_func, range(100))
chciałbym to jednak zrobić bez konieczności tworzenia nowych procesów.
Wiem o GIL. Jednak w moim przypadku użycia funkcja będzie funkcją C związaną z IO, dla której opakowanie Pythona zwolni GIL przed faktycznym wywołaniem funkcji.
Czy muszę pisać własną pulę wątków?
python
multithreading
missing-features
Jaskółka oknówka
źródło
źródło
from multiprocessing.pool import ThreadPool
.I know about the GIL. However, in my usecase, the function will be an IO-bound C function for which the python wrapper will release the GIL before the actual function call.
?Odpowiedzi:
Właśnie dowiedziałem się, że faktycznie jest wątek oparte interfejs Basen w
multiprocessing
module, jednak jest nieco ukryte i nie są odpowiednio udokumentowane.Można go zaimportować za pośrednictwem
Zaimplementowano go za pomocą obojętnej klasy Process owijającej wątek python. Wątek oparte klasy procesu można znaleźć w
multiprocessing.dummy
których jest mowa w skrócie w Dokumentach . Ten fałszywy moduł podobno zapewnia cały interfejs wieloprocesowy oparty na wątkach.źródło
multiprocessing.dummy.Pool
/multiprocessing.pool.ThreadPool
są tym samym i oba są pulami wątków. Naśladują interfejs puli procesów, ale są całkowicie zaimplementowane pod kątem wątków. Zapoznaj się ponownie z dokumentami, masz to wstecz.multiprocessing.dummy
replikuje interfejs API,multiprocessing
ale nie jest niczym więcej niż opakowaniem wokółthreading
modułu”.multiprocessing
ogólnie rzecz biorąc dotyczy procesów, ale aby umożliwić przełączanie między procesami i wątkami, (przeważnie) zreplikowalimultiprocessing
interfejs APImultiprocessing.dummy
, ale wsparli go wątkami, a nie procesami. Celem jest umożliwienieimport multiprocessing.dummy as multiprocessing
zmiany kodu opartego na procesie na oparty na wątkach.W Pythonie 3 możesz używać
concurrent.futures.ThreadPoolExecutor
, tj .:Zobacz dokumentację, aby uzyskać więcej informacji i przykładów.
źródło
sudo pip install futures
ThreadPoolExecutor
amultiprocessing.dummy.Pool
?Tak i wydaje się, że ma (mniej więcej) ten sam interfejs API.
źródło
ThreadPool
jest inna niżPool
. Prawidłowy import tofrom multiprocessing.pool import ThreadPool
.Dla czegoś bardzo prostego i lekkiego (nieco zmodyfikowanego stąd ):
Aby obsługiwać połączenia zwrotne po zakończeniu zadania, możesz po prostu dodać połączenie zwrotne do krotki zadania.
źródło
Queue.get()
to blokuje) aż do zakończenia programu, po czym są automatycznie kończone.Queue.join()
faktycznie dołączy do kolejki zadań, a nie wątków roboczych. Tak więc, gdy kolejka jest pusta,wait_completion
zwraca, kończy program i wątki są zbierane przez system operacyjny.pool.wait_completion()
wraca. W rezultacie nici wciąż się budują.Witaj, aby użyć puli wątków w Pythonie, możesz użyć tej biblioteki:
a następnie do użytku, ta biblioteka robi to tak:
Wątki to żądana liczba wątków, a zadania to lista zadań, które najczęściej są mapowane do usługi.
źródło
.close()
i.join()
połączeń i który powoduje.map()
, aby zakończyć, zanim wszystkie wątki są zakończone. Tylko ostrzeżenie.Oto wynik, którego w końcu skończyłem. To zmodyfikowana wersja klas autorstwa dgorissen powyżej.
Plik:
threadpool.py
Aby skorzystać z puli
źródło
#!/usr/bin/python3
)for i, d in enumerate(delays):
a następnie ignorujeszi
wartość?i
podczas biegu.create_task
tam jest Po co to jest?Narzut związany z tworzeniem nowych procesów jest minimalny, zwłaszcza gdy są to tylko 4 z nich. Wątpię, aby była to największa zaleta wydajności Twojej aplikacji. Uprość to, zoptymalizuj, gdzie musisz i gdzie wskazują wyniki profilowania.
źródło
Nie ma wbudowanej puli opartej na wątkach. Jednak implementacja kolejki producent / konsument z
Queue
klasą może być bardzo szybka .Od: https://docs.python.org/2/library/queue.html
źródło
concurrent.futures
modułu.from multiprocessing.pool import ThreadPool
innym sposobem może być dodanie procesu do wątkowej puli kolejek
źródło