问题描述
我需要一个队列,多个线程可以将内容放入其中,多个线程可以从中读取.
I need a queue which multiple threads can put stuff into, and multiple threads may read from.
Python 至少有两个队列类,Queue.Queue 和 collections.deque,前者似乎在内部使用后者.两者都在文档中声称是线程安全的.
Python has at least two queue classes, Queue.Queue and collections.deque, with the former seemingly using the latter internally. Both claim to be thread-safe in the documentation.
但是,队列文档还指出:
However, the Queue docs also state:
collections.deque 是另一种选择无界队列的实现使用快速原子 append() 和popleft() 操作不需要锁定.
我想我不太明白:这是否意味着 deque 不是完全线程安全的?
Which I guess I don't quite unterstand: Does this mean deque isn't fully thread-safe after all?
如果是这样,我可能无法完全理解这两个类之间的区别.我可以看到 Queue 添加了阻塞功能.另一方面,它失去了一些双端队列功能,例如支持 in-operator.
If it is, I may not fully understand the difference between the two classes. I can see that Queue adds blocking functionality. On the other hand, it loses some deque features like support for the in-operator.
直接访问内部deque对象,是
Accessing the internal deque object directly, is
队列中的 x().deque
线程安全?
此外,当 deque 已经是线程安全的时,为什么 Queue 还要为其操作使用互斥锁?
Also, why does Queue employ a mutex for it's operations when deque is thread-safe already?
推荐答案
Queue.Queue
和 collections.deque
有不同的用途.Queue.Queue 旨在允许不同的线程使用排队的消息/数据进行通信,而 collections.deque
仅用作数据结构.这就是为什么 Queue.Queue
有像 put_nowait()
、get_nowait()
和 join()
这样的方法,而collections.deque
没有.Queue.Queue
不打算用作集合,这就是为什么它缺少 in
运算符之类的原因.
Queue.Queue
and collections.deque
serve different purposes. Queue.Queue is intended for allowing different threads to communicate using queued messages/data, whereas collections.deque
is simply intended as a datastructure. That's why Queue.Queue
has methods like put_nowait()
, get_nowait()
, and join()
, whereas collections.deque
doesn't. Queue.Queue
isn't intended to be used as a collection, which is why it lacks the likes of the in
operator.
归结为:如果您有多个线程并且您希望它们能够在不需要锁的情况下进行通信,那么您正在寻找Queue.Queue
;如果您只想要一个队列或双端队列作为数据结构,请使用 collections.deque
.
It boils down to this: if you have multiple threads and you want them to be able to communicate without the need for locks, you're looking for Queue.Queue
; if you just want a queue or a double-ended queue as a datastructure, use collections.deque
.
最后,访问和操作 Queue.Queue
的内部双端队列是在玩火——你真的不想这样做.
Finally, accessing and manipulating the internal deque of a Queue.Queue
is playing with fire - you really don't want to be doing that.
这篇关于Queue.Queue 与 collections.deque的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!