清除python3中的asyncio队列的正确方法?

use*_*419 5 python python-3.x python-asyncio

生产者/消费者协程中的错误可能将项目和未完成的任务留在asyncio队列中。如果遇到错误,我只想停止循环,取消挂起的任务并清除队列。尽管我可以完成前两件事,但是我找不到清除队列的简便方法。阅读此答案后,我想出了三种方法:

import asyncio

q=asyncio.Queue()
for i in range(5):
    q.put_nowait(i)
q.get_nowait()

loop=asyncio.get_event_loop()

#this will raise an error if q cannot join
loop.run_until_complete(asyncio.wait_for(q.join(),1))

#method 1
q._queue.clear()
q._finished.set()
q._unfinished_tasks = 0

#method 2
for _ in range(q.qsize()):
    q.get_nowait()
for _ in range(q._unfinished_tasks):
    q.task_done()

#method 3
del q
q=asyncio.Queue()
Run Code Online (Sandbox Code Playgroud)

那么哪个更好呢?

cox*_*ley 7

避免使用“私有”方法。来自以下文档Queue.task_done

对于用于获取任务的每个 get(),随后对 task_done() 的调用会告诉队列该任务的处理已完成。


def empty_queue(q: asyncio.Queue):
  while not q.empty():
    # Depending on your program, you may want to
    # catch QueueEmpty
    q.get_nowait()
    q.task_done()

Run Code Online (Sandbox Code Playgroud)


Law*_*iro -3

我在各种DBussy 示例脚本中执行了此操作:

for task in asyncio.Task.all_tasks(loop) :
    task.cancel()
    try :
        loop.run_until_complete(task)
    except asyncio.CancelledError :
        pass
    #end try
#end for
Run Code Online (Sandbox Code Playgroud)

  • 问题是关于“asyncio.Queue” (2认同)