栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何使用Python asyncio限制并发性?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何使用Python asyncio限制并发性?

在阅读本答案的其余部分之前,请注意,惯用的方法是使用asyncio来限制并行任务的数量

asyncio.Semaphore
,优雅地抽象了该方法。这个答案包含有效的方法,但要实现这一点则要复杂得多。我留下答案的原因是,在某些情况下,这种方法比信号量具有优势,特别是当要完成的工作量很大或不受限制时,并且您无法提前创建所有协程。在这种情况下,第二个(基于队列的)解决方案就是您想要的答案。但是在大多数常规情况下,例如通过aiohttp并行下载,您应该使用信号量。


基本上,您需要一个固定大小的下载任务

asyncio
虽然没有预先创建的任务池,但是创建一个任务池很容易:只需保留一组任务,不要让它超出限制。尽管这个问题表明您不愿意这样做,但是代码的结尾却更加优雅:

async def download(pre):    wait_time = randint(1, 3)    print('downloading {} will take {} second(s)'.format(pre, wait_time))    await asyncio.sleep(wait_time)  # I/O, context will switch to main function    print('downloaded {}'.format(pre))async def main(loop):    no_concurrent = 3    dltasks = set()    i = 0    while i < 9:        if len(dltasks) >= no_concurrent: # Wait for some download to finish before adding a new one _done, dltasks = await asyncio.wait(     dltasks, return_when=asyncio.FIRST_COMPLETED)        dltasks.add(loop.create_task(download(i)))        i += 1    # Wait for the remaining downloads to finish    await asyncio.wait(dltasks)

一种替代方法是创建一定数量的协程进行下载,就像固定大小的线程池一样,并使用来喂它们工作

asyncio.Queue
。这消除了手动限制下载数量的需要,下载数量将自动受到协程调用数量的限制
download()

# download() defined as aboveasync def download_worker(q):    while True:        pre = await q.get()        await download(pre)        q.task_done()async def main(loop):    q = asyncio.Queue()    workers = [loop.create_task(download_worker(q)) for _ in range(3)]    i = 0    while i < 9:        await q.put(i)        i += 1    await q.join()  # wait for all tasks to be processed    for worker in workers:        worker.cancel()    await asyncio.gather(*workers, return_exceptions=True)

至于您的其他问题,显而易见的选择是

aiohttp



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/374056.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号