我需要一个队列,多个线程可以把东西放进去,多个线程可以从中读取。
Python至少有两个队列类,queue。Queue和collections.deque,前者似乎在内部使用后者。两者在文档中都声称是线程安全的。
然而,Queue文档还声明:
Collections.deque是另一种选择
实现无界队列
使用快速原子append()和
Popleft()操作
需要锁定。
我想我不太理解:这是否意味着deque不是完全线程安全的?
如果是的话,我可能无法完全理解这两个类的区别。我可以看到Queue增加了阻塞功能。另一方面,它失去了一些deque特性,比如对in-operator的支持。
直接访问内部deque对象是
Queue().deque . x
线程安全?
另外,当deque已经是线程安全的时候,为什么Queue还为它的操作使用互斥量呢?
如果您所寻找的只是线程间传输对象的线程安全方法,那么这两种方法都可以工作(对于FIFO和LIFO都可以)。先进先出:
Queue.put()和Queue.get()是线程安全的
Deque.append()和deque.popleft()是线程安全的
注意:
deque上的其他操作可能不是线程安全的,我不确定。
Deque不会阻塞pop()或popleft(),所以在新条目到达之前,你不能将你的消费线程流基于阻塞。
然而,deque似乎具有显著的效率优势。以下是使用CPython 2.7.3插入和删除100k项的一些以秒为单位的基准测试结果
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