在multiprocessing.Pool中被调用时request.get挂起

Dav*_*542 5 python optimization performance multiprocessing python-requests

我有以下代码:

def process_url(url):
    print '111'
    r = requests.get(url)
    print '222' # <-- never even gets here
    return


urls_to_download = [list_or_urls]
PARALLEL_WORKERS = 4

pool = Pool(PARALLEL_WORKERS)
pool.map_async(process_url, urls_to_download)
pool.close()
pool.join()
Run Code Online (Sandbox Code Playgroud)

每次执行此操作时,它都会运行前四个项目,然后挂起。我认为这不是超时问题,因为下载四个URL的速度非常快。它只是在获取前四个后就无限期地挂起。

我需要怎么做才能解决这个问题?

Cha*_*wal 0

问题

即使这个问题使用 python 2,您仍然可以在 python 3 中重现这个“错误”。发生这种情况是因为返回类AsyncResultpool.async_map的对象。要接收调用的结果(或在发生错误时回溯),您需要使用. 加入池在这里不起作用,因为工作已经完成,结果是一个类似于 Promise 的行为。async_mapget()AsyncResult

那么,解决办法是什么呢?

简单地,添加一个调用来等待收到结果:

from multiprocessing import Pool
import requests

def process_url(url):
    print('111')
    r = requests.get(url)
    print('222') # <-- never even gets here (not anymore!)
    return


if __name__ == "__main__":
    urls_to_download = ['https://google.com'] * 4
    PARALLEL_WORKERS = 4

    pool = Pool(PARALLEL_WORKERS)
    a = pool.map_async(process_url, urls_to_download)
    
    # Add call here
    a.get()

    pool.close()
    pool.join()
Run Code Online (Sandbox Code Playgroud)

输出

111
111
111
111
222
222
222
222
Run Code Online (Sandbox Code Playgroud)