【问题标题】:Proper way to clear an asyncio queue in python3?在 python3 中清除异步队列的正确方法?
【发布时间】:2018-02-18 19:14:03
【问题描述】:

我的生产者/消费者协程中的错误可能会将项目和未完成的任务留在异步队列中。如果遇到错误,我想简单地停止循环,取消挂起的任务并清除队列。虽然我可以完成前两件事,但我找不到清除队列的简单方法。看完this answer,我想出了三个方法:

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()

那么哪个更好呢?

【问题讨论】:

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


【解决方案1】:

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

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


def empty_queue(q: asyncio.Queue):
  for _ in range(q.qsize()):
    # Depending on your program, you may want to
    # catch QueueEmpty
    q.get_nowait()
    q.task_done()

【讨论】:

    【解决方案2】:

    我在各种DBussy example scripts

    for task in asyncio.Task.all_tasks(loop) :
        task.cancel()
        try :
            loop.run_until_complete(task)
        except asyncio.CancelledError :
            pass
        #end try
    #end for
    

    【讨论】:

    • 问题是关于asyncio.Queue
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2013-02-14
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多