如何同时 运行 `n` python 协程?

How do I run `n` python coroutines concurrently?

我已经用 async def 创建了一个 async python 协程,我想 运行 它遍历列表中的每个元素。

但是,协程启动一个单独的进程,我的电脑资源有限,所以我想同时只运行 n个这些协程。一个完成后,我想开始另一个。

我仍在学习 asyncio,但我不知道如何在此框架内执行此操作。

我知道我可以 运行 n 作业同时使用像这样的东西:

commands = asyncio.gather(*[run_command(f) for f in islice(my_large_list,n)])
# Run the commands
results = loop.run_until_complete(commands)

但是,我不知道如何在每个作业完成时替换它。

一种选择是使用 asyncio.Semaphore:

import asyncio

import random

s = asyncio.Semaphore(5)


async def my_coroutine(i):
    async with s:
        print("start", i)
        await asyncio.sleep(random.uniform(1, 3))
        print("end", i)


loop = asyncio.get_event_loop()
tasks = [my_coroutine(i + 1) for i in range(50)]
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()

Update: concurrent.futures 可能比 asycnio 更容易解决你的问题,因为执行者有一个非常简单的 max_workers 参数:

import concurrent.futures
import time

import random


def my_routine(i):
    print("start", i)
    # Here you can use subprocess.* for anything, instead we will sleep:
    time.sleep(random.uniform(1, 3))
    print("end", i)
    return "i={}".format(i)


with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
    jobs = {executor.submit(my_routine, i + 1) for i in range(50)}
    for fut in concurrent.futures.as_completed(jobs):
        print(fut.result())

print('done')