这个deque是否在python中是线程安全的?

时间:2011-12-18 19:20:48

标签: python thread-safety deque

我无法确定以下双端队列是否是线程安全的 简而言之,我创建了一个带有双端队列的类,它在新线程中每1秒显示一次其内容(因此在打印时不会暂停主程序)。
从主线填充双端队列,所以基本上应该有碰撞的机会 但是,deque是使用类方法填充的,所以基本上它是从实例本身访问的,因此来自同一个线程。
这是简化的代码:

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)

因此,虽然在实例中添加和删除队列中的项目,但是由于从实例外部调用添加函数会有风险吗?

编辑:
因为我需要修改deque中的项目,所以我不得不使用Deque。我所做的是:对给定项目进行roatate(),弹出,修改,将其推回并旋转()将其恢复到原始位置。
除非我找到一种在队列中实现修改项目的方法,否则我将不得不坚持使用Deque

4 个答案:

答案 0 :(得分:16)

对于来自对方的追加和弹出,Deque是线程安全的(http://docs.python.org/library/collections.html#deque-objects)。 Beneath here,文档只提到append()和popleft()是线程安全的。

Queue本身有一个线程安全的实现。所以你应该使用它,除非你有一些奇怪的要求。

答案 1 :(得分:3)

有关信息,有一个针对deque thread-safety(https://bugs.python.org/issue15329)引用的Python票证。

标题“澄清哪种deque方法是线程安全的”,底线是:

  

deque的append(),appendleft(),pop(),popleft()和len(d)   操作在CPython中是线程安全的。追加方法有一个   最后的DECREF(对于设置了maxlen的情况),但是这个   在所有结构更新完成后发生   不变量已经恢复,所以可以处理这些操作   原子。

无论如何,如果你不是100%确定并且你更喜欢可靠性而不是性能,那么只需为print self.q.popleft()self.q.append(val)添加类似的锁;)

答案 2 :(得分:2)

这里是双端队列作者。

MyQueue()类对我来说看起来是正确的(至少就线程安全性而言)。

append() popleft()方法都是原子方法。

代码确实需要 EAFP 逻辑来处理输入为空的情况:

wordpad

答案 3 :(得分:0)

Queue模块可能对您有用:http://docs.python.org/library/queue.html