Nie widziałem wyraźnych przykładów przypadków użycia dla Pool.apply , Pool.apply_async i Pool.map . Używam głównie Pool.map
; jakie są zalety innych?
źródło
Nie widziałem wyraźnych przykładów przypadków użycia dla Pool.apply , Pool.apply_async i Pool.map . Używam głównie Pool.map
; jakie są zalety innych?
W dawnych czasach Pythona, aby wywołać funkcję z dowolnymi argumentami, użyłbyś apply
:
apply(f,args,kwargs)
apply
nadal istnieje w Python2.7, ale nie w Python3 i generalnie nie jest już używany. Dzisiaj,
f(*args,**kwargs)
jest preferowany. Te multiprocessing.Pool
moduły stara się zapewnić podobny interfejs.
Pool.apply
jest jak Python apply
, z tym wyjątkiem, że wywołanie funkcji jest wykonywane w osobnym procesie. Pool.apply
blokuje do zakończenia funkcji.
Pool.apply_async
jest również podobny do wbudowanego w Pythona apply
, z tym wyjątkiem, że wywołanie natychmiast wraca zamiast czekać na wynik. AsyncResult
Zwracany jest obiekt. Wywołujesz jego get()
metodę, aby pobrać wynik wywołania funkcji. Te get()
metody bloki aż funkcja jest zakończona. Jest zatem pool.apply(func, args, kwargs)
równoważny z pool.apply_async(func, args, kwargs).get()
.
W przeciwieństwie do Pool.apply
The Pool.apply_async
metoda ma również wywołania zwrotnego, która, jeśli dostarczone, jest wywoływana, gdy funkcja jest kompletna. Można tego użyć zamiast dzwonić get()
.
Na przykład:
import multiprocessing as mp
import time
def foo_pool(x):
time.sleep(2)
return x*x
result_list = []
def log_result(result):
# This is called whenever foo_pool(i) returns a result.
# result_list is modified only by the main process, not the pool workers.
result_list.append(result)
def apply_async_with_callback():
pool = mp.Pool()
for i in range(10):
pool.apply_async(foo_pool, args = (i, ), callback = log_result)
pool.close()
pool.join()
print(result_list)
if __name__ == '__main__':
apply_async_with_callback()
może dać wynik taki jak
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Zwróć uwagę, w przeciwieństwie pool.map
do kolejności wyników, może nie odpowiadać kolejności, w której pool.apply_async
połączenia zostały wykonane.
Jeśli więc chcesz uruchomić funkcję w osobnym procesie, ale chcesz, aby bieżący proces był blokowany, dopóki funkcja nie powróci, użyj Pool.apply
. Jak Pool.apply
, Pool.map
bloki aż do całkowitego wyniku jest zwracana.
Jeśli chcesz, aby pula procesów roboczych wykonywała wiele wywołań funkcji asynchronicznie, użyj Pool.apply_async
. Kolejność wyników nie jest gwarantowana być taka sama jak kolejność wywołań Pool.apply_async
.
Zauważ też, że możesz wywołać wiele różnych funkcji za pomocą Pool.apply_async
(nie wszystkie połączenia muszą korzystać z tej samej funkcji).
Natomiast Pool.map
stosuje tę samą funkcję do wielu argumentów. Jednak w przeciwieństwie Pool.apply_async
do wyników zwracane są w kolejności odpowiadającej kolejności argumentów.
if __name__=="__main__"
wcześniejapply_async_with_callback()
w systemie Windows?Pool.map(func,iterable)
jest to równoważne zPool.map_async(func,iterable).get()
. Tak więc związek pomiędzyPool.map
iPool.map_async
jest podobny do tego zPool.apply
iPool.apply_async
. Teasync
polecenia wrócić natychmiast, nieposiadającyasync
polecenia blokowania. Teasync
polecenia mają też zwrotnego.Pool.map
iPool.apply
jest podobne do decydowania, kiedy użyćmap
lubapply
w Pythonie. Wystarczy użyć narzędzia, które pasuje do pracy. Decyzja między użyciem wersjiasync
aasync
wersją inną zależy od tego, czy chcesz, aby wywołanie blokowało bieżący proces i / lub czy chcesz użyć wywołania zwrotnego.apply_async
zwracaApplyResult
obiekt. Wywołanie żeApplyResult
„sget
metoda zwróci wartość zwracaną Associated funkcja (lub podbiciemp.TimeoutError
jeśli czasy-out połączenia). Więc jeśli umieścićApplyResult
s w uporządkowanej listy, a następnie wywołanie ichget
metody zwróci wyniki w tej samej kolejności. Możesz jednak użyćpool.map
w tej sytuacji.W odniesieniu
apply
domap
:pool.apply(f, args)
:f
jest wykonywany tylko w JEDNEJ z pracowników puli. Uruchomi się JEDEN z procesów w pulif(args)
.pool.map(f, iterable)
: Ta metoda dzieli iterowalny fragment na kilka części, które przekazuje do puli procesów jako osobne zadania. Wykorzystujesz więc wszystkie procesy w puli.źródło
apply_async()
8 razy? Czy automatycznie obsłuży to w kolejce?Oto przegląd w formie tabeli w celu pokazania różnic między
Pool.apply
,Pool.apply_async
,Pool.map
iPool.map_async
. Wybierając jeden, musisz wziąć pod uwagę wiele argumentów, współbieżność, blokowanie i porządkowanie:Uwagi:
Pool.imap
orazPool.imap_async
- leniwsza wersja mapy i map_async.Pool.starmap
metoda, bardzo podobna do metody mapy, poza tym akceptacja wielu argumentów.Async
metody przesyłają wszystkie procesy naraz i pobierają wyniki po ich zakończeniu. Użyj metody get, aby uzyskać wyniki.Pool.map
(lubPool.apply
) metody są bardzo podobne do wbudowanej mapy Pythona (lub zastosowania). Blokują główny proces, dopóki wszystkie procesy się nie zakończą, i zwracają wynik.Przykłady:
mapa
Jest wywoływany do listy zadań w jednym czasie
zastosować
Można wezwać tylko do jednej pracy
map_async
Jest wywoływany do listy zadań w jednym czasie
Apply_async
Można wywołać tylko dla jednego zadania i równolegle wykonuje ono zadanie w tle
starmap
Jest wariantem,
pool.map
który obsługuje wiele argumentówstarmap_async
Kombinacja starmap () i map_async (), która iteruje po iterable iterable i wywołuje func z iterables po rozpakowaniu. Zwraca wynikowy obiekt.
Odniesienie:
Znajdź pełną dokumentację tutaj: https://docs.python.org/3/library/multiprocessing.html
źródło