Я не видел четких примеров с примерами использования для 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?