Я не видел четких примеров с примерами использования для 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
, результаты возвращаются в порядке, соответствующем порядку аргументов.
if __name__=="__main__"
раньшеapply_async_with_callback()
на Windows?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
«Sget
метод вернет возвращаемое значение ассоциированной функции (или рейз ,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
. При выборе одного из них вы должны учитывать несколько аргументов, параллелизм, блокировку и упорядочение:Ноты:
Pool.imap
иPool.imap_async
- более лёгкая версия карты и map_async.Pool.starmap
метод, очень похожий на метод map, кроме того, он принимает несколько аргументов.Async
методы отправляют все процессы одновременно и извлекают результаты после их завершения. Используйте метод get для получения результатов.Pool.map
(илиPool.apply
) методы очень похожи на встроенную карту Python (или применяются). Они блокируют основной процесс до завершения всех процессов и возвращают результат.Примеры:
карта
Вызывается список вакансий за один раз
подать заявление
Можно вызвать только на одну работу
map_async
Вызывается список вакансий за один раз
apply_async
Может быть вызван только для одного задания и выполняет задание в фоновом режиме параллельно
Starmap
Есть вариант,
pool.map
который поддерживает несколько аргументовstarmap_async
Комбинация starmap () и map_async (), которая перебирает итерируемые итерируемые элементы и вызывает func с неупакованными итераблами. Возвращает объект результата.
Ссылка:
Найти полную документацию здесь: https://docs.python.org/3/library/multiprocessing.html
источник