Я не видел четких примеров с примерами использования для Pool.apply , Pool.apply_async и Pool.map . Я в основном использую Pool.map
; каковы преимущества других?
Я не видел четких примеров с примерами использования для Pool.apply , Pool.apply_async и Pool.map . Я в основном использую Pool.map
; каковы преимущества других?
Ответы:
В старые времена Python для вызова функции с произвольными аргументами вы использовали бы apply
:
apply(f,args,kwargs)
apply
все еще существует в Python2.7, но не в Python3, и обычно больше не используется. В наше время,
f(*args,**kwargs)
является предпочтительным. В multiprocessing.Pool
модулях пытаются обеспечить подобный интерфейс.
Pool.apply
похоже на Python apply
, за исключением того, что вызов функции выполняется в отдельном процессе. Pool.apply
блокирует, пока функция не будет завершена.
Pool.apply_async
также как встроенный в Python apply
, за исключением того, что вызов возвращается немедленно, а не в ожидании результата. AsyncResult
Объект возвращается. Вы вызываете его get()
метод для получения результата вызова функции. В get()
методе блокируется , пока эта функция будет завершено. Таким образом, pool.apply(func, args, kwargs)
эквивалентно pool.apply_async(func, args, kwargs).get()
.
В отличие от этого Pool.apply
, Pool.apply_async
метод также имеет обратный вызов, который, если он предоставляется, вызывается, когда функция завершена. Это можно использовать вместо звонка get()
.
Например:
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()
может дать такой результат, как
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Обратите внимание, в отличие от pool.map
, порядок результатов может не соответствовать порядку, в котором pool.apply_async
были сделаны звонки.
Итак, если вам нужно запустить функцию в отдельном процессе, но вы хотите, чтобы текущий процесс блокировался до тех пор, пока эта функция не вернется, используйте Pool.apply
. Мол Pool.apply
, Pool.map
блоки, пока не вернется полный результат.
Если вы хотите, чтобы пул рабочих процессов выполнял много вызовов функций асинхронно, используйте Pool.apply_async
. Порядок результатов не гарантируется быть такой же , как и порядок звонков в Pool.apply_async
.
Также обратите внимание, что вы можете вызывать несколько различных функций Pool.apply_async
(не все вызовы должны использовать одну и ту же функцию).
Напротив, Pool.map
применяется одна и та же функция ко многим аргументам. Однако, в отличие от этого Pool.apply_async
, результаты возвращаются в порядке, соответствующем порядку аргументов.
Pool.map(func,iterable)
это эквивалентно Pool.map_async(func,iterable).get()
. Таким образом, отношения между Pool.map
и Pool.map_async
похожи на отношения Pool.apply
и Pool.apply_async
. Эти async
команды возвращают немедленно, в то время как не- async
команды блокировать. Эти async
команды также имеют функцию обратного вызова.
Pool.map
и Pool.apply
аналогичен решению, когда использовать map
или apply
в Python. Вы просто используете инструмент, который подходит для работы. Выбор между использованием async
и не- async
версией зависит от того, хотите ли вы, чтобы вызов блокировал текущий процесс, и / или если вы хотите использовать обратный вызов.
apply_async
возвращает ApplyResult
объект. Вызов , который ApplyResult
«S get
метод вернет возвращаемое значение ассоциированной функции (или рейз , mp.TimeoutError
если время-вызов из.) Так что, если вы положили ApplyResult
с в упорядоченном списке, то вызов их get
методы будут возвращать результаты в том же порядке. Вы можете просто использовать pool.map
в этой ситуации, однако.
Относительно apply
против map
:
pool.apply(f, args)
: f
выполняется только в одном из работников бассейна. Таким образом, ОДИН из процессов в пуле будет работать f(args)
.
pool.map(f, iterable)
Этот метод разделяет итерируемое на несколько частей, которые он отправляет в пул процессов как отдельные задачи. Таким образом, вы используете все процессы в пуле.
apply_async()
8 раз? Будет ли он автоматически обрабатывать его с очередью?
Вот краткий обзор в виде таблицы для того , чтобы показать разницу между Pool.apply
, Pool.apply_async
, Pool.map
и Pool.map_async
. При выборе одного из них вы должны учитывать несколько аргументов, параллелизм, блокировку и упорядочение:
| Multi-args Concurrence Blocking Ordered-results
---------------------------------------------------------------------
Pool.map | no yes yes yes
Pool.map_async | no yes no yes
Pool.apply | yes no yes no
Pool.apply_async | yes yes no no
Pool.starmap | yes yes yes yes
Pool.starmap_async| yes yes no no
Pool.imap
и Pool.imap_async
- более лёгкая версия карты и map_async.
Pool.starmap
метод, очень похожий на метод map, кроме того, он принимает несколько аргументов.
Async
методы отправляют все процессы одновременно и извлекают результаты после их завершения. Используйте метод get для получения результатов.
Pool.map
(или Pool.apply
) методы очень похожи на встроенную карту Python (или применяются). Они блокируют основной процесс до завершения всех процессов и возвращают результат.
Вызывается список вакансий за один раз
results = pool.map(func, [1, 2, 3])
Можно вызвать только на одну работу
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
Вызывается список вакансий за один раз
pool.map_async(func, jobs, callback=collect_result)
Может быть вызван только для одного задания и выполняет задание в фоновом режиме параллельно
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
Есть вариант, pool.map
который поддерживает несколько аргументов
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
Комбинация starmap () и map_async (), которая перебирает итерируемые итерируемые элементы и вызывает func с неупакованными итераблами. Возвращает объект результата.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Найти полную документацию здесь: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
раньшеapply_async_with_callback()
на Windows?