如何 运行 多次异步函数?

How to run async function multiple times?

如何 运行 多次运行?

我想重新运行循环,以便程序多执行几次函数。我知道这不是正确的方法。但肯定有解决方法吗?

我的代码:

from asyncio import get_event_loop, gather, sleep


async def main(k):
    print(k)
    await sleep(1)


if __name__ == '__main__':
        count_run = 3
        count_group = 3
        list_objects = list()

        for i in range(1, 11):
        list_objects.append(i)

        list_func = [main(x) for x in list_objects]

        run_groups = [list_func[i:i + count_group] for i in range(0, len(list_func), count_group)]

        loop = get_event_loop()

        for _ in range(count_run):
           for rg in run_groups:
               loop.run_until_complete(gather(*rg))

现在我收到一个错误:

RuntimeError: cannot reuse already awaited coroutine

您通过在 list_func 中为 list_objects 的每个元素调用 main() 创建一个等待列表,然后在 run_groups 中创建该列表的一堆切片,将 awaitable 分成 3 组。然后您一次启动这些组,导致 awaitables 执行和 return - 一旦您启动了每个组并且等待了每个 awaitable ,您就不能再次等待它们,您将不得不创建新的可等待对象。

使代码正常工作的最简单方法是仅更改顺序并在外循环中创建可等待对象:

from asyncio import get_event_loop, gather, sleep


async def main(k):
    print(k)
    await sleep(1)


if __name__ == '__main__':
    count_run = 3
    count_group = 3
    list_objects = list()

    for i in range(1, 11):
        list_objects.append(i)

    loop = get_event_loop()

    for _ in range(count_run):
        list_func = [main(x) for x in list_objects]

        run_groups = [list_func[i:i + count_group] for i in range(0, len(list_func), count_group)]
        for rg in run_groups:
           loop.run_until_complete(gather(*rg))

注意:我还修复了代码示例中的缩进问题,假设这些问题只是问题文本中 copy/paste 问题的结果。

代码现在可以工作了,因为 list_func 中的每个 awaitable 只被 gather 调用等待一次(以 3 为一组),并且在循环完成之前所有这些都被等待。在外循环的每次迭代中,都会创建一个新的可等待对象列表,以便能够重复该过程,因为每个可等待对象只能等待一次。

另一种方法是先创建所有可等待对象,然后循环遍历它们:

from asyncio import get_event_loop, gather, sleep


async def main(k):
    print(k)
    await sleep(1)


if __name__ == '__main__':
    count_run = 3
    count_group = 3
    list_objects = list()

    for i in range(1, 11):
        list_objects.append(i)

    loop = get_event_loop()

    list_func = []
    for _ in range(count_run):
        list_func.extend([main(x) for x in list_objects])

    run_groups = [list_func[i:i + count_group] for i in range(0, len(list_func), count_group)]
    for rg in run_groups:
       loop.run_until_complete(gather(*rg))

从时间上的差异,你可以看出它现在一直以 3 个为一组执行,但是继续执行“7 8 9”、“10 1 2”等,直到执行完所有 30 个。

主要区别在于 list_func 现在包含所有 30 个等待对象,然后再执行它们,而不是创建 3 次新的等待对象。