首页 > 解决方案 > 当线程可用时,使 ThreadPoolExecutor 获取下一个 url

问题描述

(为了简化事情,我将问题简化为简单的事情)。

假设我是一个票据端点,我可以从中获取结果,例如www.example.com/api/id=2,12,20返回带有 id 的票据,2,12并且20API 允许我们每次调用获取 3 个 id,并且我有 4 个线程的限制(仅用于说明目的)

然后我有 30 个我想要获取的 id,因此我想使用多线程(我知道,asyncio但我想使用多线程来进行学习),第一个线程得到id=1,2,3,第二个线程得到id=4,5,6..,第四个线程得到id=10,11,12。当任何一个线程完成时,它们就会获取下一个 id 序列。

我有一个生成器get_ids(),它返回要获取的 id,例如

def get_ids(ids,step_size):
   """
   returns bulks of "step_size" from the list "ids
   """
   for i in range(len(ids)//step_size):
      yield ids[i*step_size:(i+1)*step_size]  

和一个返回结果的函数:

def get_res(ids):
    print("Hello world!")

    url = r'www.example.com/api/id='+",".join(ids)
    r = requests.get(url)
    return r.json()

我试着用ThreadPoolExecutor

with ThreadPoolExecutor(max_workers = 4) as executor:
    RESULTS = []
    for ids in get_ids(list_of_ids,step_size=3):
       RESULTS.append(executor.submit(get_res(ids)))

我只是没有得到任何加速。似乎没有产生线程;前 4 次 "hello world"打印不会立即出现,而是在一些延迟之后依次出现,并且与第 5 次和第 6 次等速度相同。

我认为ThreadPoolExecutor上下文管理器max_workers会自动生成线程,但我是否需要手动RESULTS.append(...) max_workers计算时间,但在这种情况下,如果我有 50 个线程怎么办?

编辑:

我通过使用mapie使它工作

gids = get_ids(list_of_ids,step_size=3)

with ThreadPoolExecutor(max_workers = 4) as executor:
    RESULTS = []
    gids = get_ids(list_of_ids,step_size=3)
    RESULTS.append(executor.map(get_res,gids))

标签: multithreading

解决方案


推荐阅读