Python 如何使线程池更好地处理请求

Python 如何使线程池更好地处理请求,python,python-requests,multiprocessing,Python,Python Requests,Multiprocessing,我现在有这个函数,它做一个api调用,每个api调用都请求不同的数据。我一次最多可以执行300个并发api调用 这样做似乎并不快,因为这只是等待repl,我想知道如何使这个函数更快 from multiprocessing.pool import ThreadPool import requests pool = ThreadPool(processes=500) variables = VariableBaseDict for item in variables: async_res

我现在有这个函数,它做一个api调用,每个api调用都请求不同的数据。我一次最多可以执行300个并发api调用

这样做似乎并不快,因为这只是等待repl,我想知道如何使这个函数更快

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

您当前的代码实际上并没有将任何实际工作转移到辅助线程。您正在主线程中调用
requests.get(url.json())
,然后将返回的对象传递到
池。apply\u async
。您应该执行
pool.apply_async(requests.get,(url.json(),)
。也就是说,即使您纠正了这个问题,您也会立即等待呼叫的回复,这意味着您实际上从未同时运行任何呼叫。您将一个项目转移到一个线程,等待它完成,然后等待下一个项目

您需要:

  • 修复意外调用
    请求的问题。在主线程中获取(…)
  • 使用
    pool.map
    将工作列表并发地分配给工作线程,或者继续使用
    pool.apply_async
    ,但不要立即调用
    async_result.get()
    ,而是将所有
    async_result
    对象存储在一个列表中,并在迭代
    变量之后,迭代
    async\u结果
    列表,并对每个项目调用
    .get()
    。这样,您实际上可以同时运行所有调用
  • 因此,如果您使用
    apply\u 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])
    

    不过,url在每次请求时都会发生变化,比如额外的变量,即“id=3”vs“id=10”@nadermx,这很好,在这种情况下,您只需使用
    (假设您实际正在构建url)。