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

标签 python python-3.x queue python-asyncio

在我制作的另一个使用 asyncio 的程序中,我遇到以下问题:

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

我的解决方案是创建某种全局队列,将协程添加到其中,这样运行时间就不会影响顺序,我做了一个小测试,但无法让它正常工作。

我尝试使用 while not co.done() 循环,但它似乎只能在任务完成后才能解决

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

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() 甚至在您将协程从队列中弹出并等待之前就安排它们运行。如果我理解正确的话,这里对 asyncio.create_task() 的调用是不必要的(对 asyncio.wait() 的调用也是如此)。您可以像这样简单地重构您的 main() 函数,它将按照 FIFO 顺序运行任务,并且一次只会运行一个任务:

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

关于Python Asyncio 如何从队列中连续运行任务/协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57450276/

相关文章:

python - Numpy:创建 Python 对象的浅拷贝数组

python - 如何在 sqlalchemy 中正确关闭 mysql 连接?

python - 如何根据给定的标准将一个csv文件拆分为多个csv?

c - python 中参数/变量的存储限制

python - PyQt5 : Destroyed while thread is still running

python - 如何在 Python 中关闭线程?

python - 限制 *Large* Django QuerySet 中的内存使用

python - Python 中列表的 bool 值

c# - 如何将多个异步方法设置到队列中?

java - 我怎样才能解决这个涉及具有最小内存需求的队列的 Java 编程挑战?