25

是否可以Queue在不调用 Python 的情况下检查 a 中的项目.get()?根据文档,队列中不允许索引。我需要检查队列头部的项目是否满足某些条件,如果满足,请将其从队列中删除。同样,我需要检查队列中的任何其他项目是否满足类似条件并将其删除。

我在这里使用了错误的数据结构吗?

4

3 回答 3

27

queue_object.queue 将在 deque 对象中返回队列的副本,然后您可以使用其切片。当然,它不会与原始队列同步,但可以让您在复制时查看队列。

有一个很好的理由说明为什么你不想这样做,在这个线程comp.lang.python - Queue peek 中有详细解释。. 但是,如果您只是想了解 Queue 的工作原理,这是一种简单的方法。

import Queue
q = Queue.Queue()
q.push(1)
q.put('foo')
q.put('bar')
d = q.queue
print(d)
deque(['foo', 'bar'])
print(d[0])
'foo'
于 2013-05-22T07:58:15.133 回答
10

Queue模块实现了多生产者、多消费者队列。当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。

如您所见,该Queue模块是专门为与线程一起使用而创建的,仅提供FIFOLIFO优先级队列,它们都没有提供此功能。但是通过检查模块的源代码Queue您可以看到它只是使用一个collections.deque(双端队列)可以轻松完成您的任务。您可以索引第一项 ( [0]) 并且.popleft()在恒定时间内。

于 2013-05-22T08:37:02.200 回答
6

简单地访问底层队列是不安全的。

安全的方法是扩展 Queue 类。如果您返回底层 dequeue 对象,您将不会获得副本,而是获得活动对象

这样做的结果是它可以在您迭代它时更改 - 如果在您的迭代期间另一个线程插入队列中,这将导致异常。

知道 python 使用 GIL,您可以安全地使用list(q.queue),因为 list() 永远不会导致上下文切换。

最好使用与 get() 函数相同的锁,而不是对 GIL 做出假设:

import queue
    
class SnapshotQueue(queue.Queue):
    def snapshot(self):
        with self.mutex
            return list(self.queue)

该类可以安全地使用而不是常规队列,并且它将返回队列状态的快照......在互斥锁中并且不会导致底层队列操作出现问题。

于 2020-12-01T21:40:19.487 回答