清除队列中的所有项目

OHL*_*ÁLÁ 48 python queue

我该如何清除队列.例如,我在队列中有数据,但由于某种原因,我不需要现有数据,只想清除队列.

有什么办法吗?这会工作:

oldQueue = Queue.Queue()
Run Code Online (Sandbox Code Playgroud)

Rob*_*wie 84

q = Queue.Queue()
q.queue.clear()
Run Code Online (Sandbox Code Playgroud)

编辑 为了清晰和简洁,我省略了线程安全的问题,但@Dan D非常正确,以下是更好的.

q = Queue.Queue()
with q.mutex:
    q.queue.clear()
Run Code Online (Sandbox Code Playgroud)

  • 如果你使用q.mutex:q.queue.clear()`,这个操作将是线程安全的. (15认同)
  • 根据定义,队列是线程安全的,不需要互斥锁. (10认同)
  • @DanD.如果我错了,请纠正我,但这对我来说似乎是个坏主意.`.mutex`和`.queue` [似乎没有记录](https://docs.python.org/2/library/queue.html)如果我没有弄错,使用`q.mutex`会**死锁**如果你在它的块内做任何甚至`q.get_nowait`的事情. (6认同)
  • n611x007和user2357112是正确的.我会在无证/私人成员之前使用下划线,误导我相信clear()在安全的API中.无论如何,清除队列看起来都是一个坏主意,最好阅读并删除不需要的项目. (2认同)
  • 请注意,如下面在VEO的回答中所述,仅仅清除是不够的,因为即使队列为空,相应的任务也没有被标记为已完成.这可能会导致代码锁定. (2认同)
  • 我也使用下面的方法,使用q.mutex:size = len(q.queue)q.queue.clear()q.unfinished_tasks-= size对join()阻塞的问题进行了排序 (2认同)

V.E*_*E.O 31

你只是无法清除队列,因为每个put也会添加unfinished_tasks成员.join方法取决于此值.并且还需要通知all_tasks_done.

q.mutex.acquire()
q.queue.clear()
q.all_tasks_done.notify_all()
q.unfinished_tasks = 0
q.mutex.release()
Run Code Online (Sandbox Code Playgroud)

或以合适的方式,使用get和task_done对来安全地清除任务.

while not q.empty():
    try:
        q.get(False)
    except Empty:
        continue
    q.task_done()
Run Code Online (Sandbox Code Playgroud)

或者只是创建一个新的队列并删除旧的队列.

  • 第二种方式(“体面的”方式)似乎是最安全,更优雅的方式,并且仅使用已记录的公共API。谁能确认? (2认同)

Nik*_*s R 5

这对我来说似乎做得很好。如果您错过了任何重要事项,我都欢迎发表评论/添加。

class Queue(queue.Queue):
  '''
  A custom queue subclass that provides a :meth:`clear` method.
  '''

  def clear(self):
    '''
    Clears all items from the queue.
    '''

    with self.mutex:
      unfinished = self.unfinished_tasks - len(self.queue)
      if unfinished <= 0:
        if unfinished < 0:
          raise ValueError('task_done() called too many times')
        self.all_tasks_done.notify_all()
      self.unfinished_tasks = unfinished
      self.queue.clear()
      self.not_full.notify_all()
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是最有效(调用`.clear()`)和正确(包括当前处理的项目的通知)的方式来做到这一点。 (2认同)