Python Asyncio如何从队列连续运行任务/协程

Python Asyncio how to run Tasks/Coroutines Consecutively from a Queue

在我制作的利用异步的另一个程序中,我不得不遇到以下问题:

在一个函数中,要等待两个协程(在单独的行上),但是第一个协程需要花费一些时间,在第一个协程完成之前,调用另一个函数来等待另一个协程,因为这是在第一个协程完成之前等待的,它是第二个协程尚未等待第一个函数,因此第二个函数在第一个的两个协程之间运行

我的解决方案是制作某种将要添加协程的全局队列,以便运行时不会影响订单,我做了一个小测试,但无法使其正常工作。

我尝试使用了一段时间而不是co.done()循环,但是它似乎只能在任务完成后解决

我尝试在循环外执行此操作,但是由于某种原因,它仅用一个q.get()就完成了所有任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import asyncio
from time import gmtime, strftime

async def task(name, time, queue=None):

    print(strftime("%H:%M:%S", gmtime()))
    await asyncio.sleep(time)
    print("task %s done"%(name))
    print(strftime("%H:%M:%S", gmtime()))

    if queue:

        queue.task_done()

async def main():

    q = asyncio.Queue()
    await q.put(asyncio.create_task(task("A", 3, q)))
    await q.put(asyncio.create_task(task("B", 1, q)))
    await q.put(asyncio.create_task(task("C", 1, q)))

    for i in range(3):

        co = await q.get()
        done, pending = await asyncio.wait({co})

asyncio.run(main())

我期望它可以一次又一次地完成所有任务,因此总时间为5秒。但是它会在3秒内同时运行它们,B和C首先同时完成,然后A在2秒后完成。


您的示例同时运行所有三个任务的原因是,asyncio.create_task()甚至在将协程程序从队列中弹出并await之前都安排了协程程序的运行。 如果我正确理解,则不需要在此处调用asyncio.create_task()(对asyncio.wait()的调用也是如此)。 您可以像这样简单地重构您的main()函数,它将按FIFO顺序运行任务,并且一次仅运行一个任务:

1
2
3
4
5
6
7
8
9
10
11
async def main():

    q = asyncio.Queue()
    await q.put(task("A", 3, q))
    await q.put(task("B", 1, q))
    await q.put(task("C", 1, q))

    for i in range(3):

        co = await q.get()
        await co