这个Python中的双端队列是线程安全的吗?
我不太确定下面这个双端队列(deque)是否是线程安全的。
简单来说,我创建了一个类,这个类里面有一个双端队列,每隔1秒在一个新线程中显示它的内容(这样打印的时候不会暂停主程序)。
这个双端队列是由主线程填充的,所以基本上是有可能发生冲突的。
但是,填充双端队列是通过类的方法来完成的,所以实际上是从实例内部访问的,也就是在同一个线程中。
下面是简化后的代码:
import threading
import time
from collections import deque
class MyQueue(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.q = deque()
self.start()
def run(self):
# pop out queue items every 1 sec
# (please ignore empty deque for now)
while True:
print self.q.popleft()
time.sleep(1)
def add_to_q(self, val):
# this function is called from outside
self.q.append(val)
# main
# fill the queue with values
qu = MyQueue()
for i in range(1:100):
qu.add_to_q(i)
所以,尽管添加和移除队列中的项目是在实例内部进行的,但由于添加函数是从实例外部调用的,这样是否会有风险呢?
补充说明:
因为我需要修改双端队列中的项目,所以我必须使用双端队列。我所做的就是:先旋转到指定的项目,弹出它,修改后再放回去,然后再旋转回原来的位置。
除非我找到在队列中修改项目的方法,否则我只能继续使用双端队列。
3 个回答
这里有一个关于Python的票据,提到deque(双端队列)在多线程中的安全性问题,链接在这里:https://bugs.python.org/issue15329。
标题是“明确哪些deque方法是线程安全的”,总结一下就是:
在CPython中,deque的append()、appendleft()、pop()、popleft()和len(d)这些操作是线程安全的。append方法在最后会有一个DECREF(这是在设置了最大长度的情况下),但这个操作是在所有结构更新完成后进行的,所以可以把这些操作看作是原子的,也就是说它们不会被打断。
不过,如果你不太确定,并且更看重可靠性而不是性能的话,可以在print self.q.popleft()
和self.q.append(val)
这两行代码上加个锁;这样会更安全哦!
双端队列(Deque)是线程安全的,这意味着在不同的线程中同时进行添加和删除操作时,它能保证数据的安全性。你可以在这个链接里查看详细信息:http://docs.python.org/library/collections.html#deque-objects。不过在下面的文档中,只提到append()和popleft()这两个操作是线程安全的,其他的操作没有特别说明。
此外,队列(Queue)本身也有一个线程安全的实现。所以如果你没有特别奇怪的需求,建议你使用这个线程安全的队列。