我需要一个队列,多个线程可以将内容放入其中,多个线程可以从中读取。
Python至少有两个队列类,Queue.Queue和collections.deque,前者似乎在内部使用后者。两人都声称在文档中线程安全。
但是,队列文档还声明:
collections.deque是具有快速原子追加()和popleft()操作(不需要锁定)的无界队列的替代实现。
我想我不是很难理解:这是否意味着deque并不是完全线程安全的呢?
如果是的话,我可能不完全明白这两类的不同之处。我可以看到队列增加了阻塞功能。另一方面,它失去了一些功能缺陷,如对内操作符的支持。
直接访问内部deque对象,是
X在.deque中的作用
线程安全?
另外,当deque已经是线程安全的时候,为什么使用互斥锁来执行它的操作呢?
发布于 2009-04-04 15:26:29
Queue.Queue和collections.deque的用途不同。Queue.Queue的目的是允许不同的线程使用排队的消息/数据进行通信,而collections.deque只是作为一种数据结构。这就是为什么Queue.Queue有像put_nowait()、get_nowait()和join()这样的方法,而collections.deque没有。Queue.Queue不打算用作集合,这就是为什么它缺少in操作符的原因。
归结起来是这样的:如果您有多个线程,并且希望它们能够在不需要锁的情况下进行通信,那么您正在寻找Queue.Queue;如果您只想要一个队列或一个双端队列作为数据结构,那么使用collections.deque。
最后,访问和操作Queue.Queue的内部功能是在玩火--你真的不想这样做。
发布于 2013-12-02 14:20:14
如果您所要寻找的只是,一种线程安全的方法来在线程之间传输对象,那么这两种方法都可以工作(同时适用于FIFO和LIFO)。对于FIFO:
注意:
deque上的其他操作可能不是线程安全的,我不确定。deque不会在pop()或popleft()上阻塞,因此在新项目到达之前,您不能将使用者线程流建立在阻塞上。然而,deque似乎具有显著的效率优势。下面是使用CPython 2.7.3插入和删除100 k项的一些基准测试结果(秒)
deque 0.0747888759791
Queue 1.60079066852下面是基准代码:
import time
import Queue
import collections
q = collections.deque()
t0 = time.clock()
for i in xrange(100000):
q.append(1)
for i in xrange(100000):
q.popleft()
print 'deque', time.clock() - t0
q = Queue.Queue(200000)
t0 = time.clock()
for i in xrange(100000):
q.put(1)
for i in xrange(100000):
q.get()
print 'Queue', time.clock() - t0发布于 2015-12-12 11:41:50
有关信息,有一张用于deque线程安全(https://bugs.python.org/issue15329)的Python票据。标题“澄清哪些deque方法是线程安全的”。
底线:https://bugs.python.org/issue15329#msg199368
deque的append()、附录len()、pop()、popleft()和len(d)操作在CPython中是线程安全的。追加方法在末尾有一个DECREF (对于已设置maxlen的情况),但是在所有结构更新和不变量被恢复之后就会发生这种情况,所以把这些操作当作原子操作是可以的。
不管怎么说,如果你不是100%确定,你更喜欢可靠性而不是性能,只需放置一个类似锁;)
https://stackoverflow.com/questions/717148
复制相似问题