Как мне улучшить работу ThreadPool с запросами - PullRequest
1 голос
/ 29 мая 2019

В настоящее время у меня есть эта функция, которая выполняет вызов API, каждый вызов API запрашивает разные данные.Я могу сделать до 300 одновременных вызовов API.

Похоже, что это не так быстро, потому что это просто ожидание ответа. Мне было интересно, как бы сделать эту функцию быстрее?

from multiprocessing.pool import ThreadPool
import requests

pool = ThreadPool(processes=500)
variables = VariableBaseDict
for item in variables:
    async_result = pool.apply_async(requests.get(url.json()))
    result = async_result.get()
    #do stuff with result

1 Ответ

2 голосов
/ 29 мая 2019

Ваш текущий код на самом деле не обрабатывает какую-либо реальную работу для рабочего потока.Вы вызываете requests.get(url.json()) прямо в главном потоке, а затем передаете объект, который возвращается к pool.apply_async.Вы должны делать pool.apply_async(requests.get, (url.json(),)) вместо этого.Тем не менее, даже если вы исправили эту проблему, вы сразу же ожидаете ответа на вызов, что означает, что вы никогда не выполняете никаких вызовов одновременно.Вы отправляете один элемент в цепочку, ожидаете его выполнения, затем ждете следующего элемента.

Вам необходимо:

  1. Исправить проблему, когда вы случайно оказалисьвызов requests.get(...) в главном потоке.
  2. Либо используйте pool.map для одновременной передачи списка рабочих процессов рабочим потокам, либо продолжайте использовать pool.apply_async, но вместо немедленного вызова async_result.get(), storeвсе объекты async_result в списке, и после итерации по variables выполните итерацию по списку async_result и вызовите .get() для каждого элемента.Таким образом, вы фактически выполняете все вызовы одновременно.

Итак, если бы вы использовали apply_async, вы бы сделали что-то вроде этого:

async_results = [pool.apply_async(requests.get, (build_url(item),)) for item in variables]
for ar in async_results:
    result = ar.get()
    # do stuff with result

С pool.map это будет:

  results = pool.map(requests.get, [build_url(item) for item in variables])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...