这在python中是否是双端队列线程安全的?

问题描述 投票:11回答:4

我无法确定以下双端队列是否是线程安全的。简而言之,我创建了一个带有双端队列的类,该双端队列每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)

因此,尽管从队列内部添加和删除项目是在实例内部进行的,但是由于从实例外部调用添加函数会存在风险吗?

编辑:由于我需要修改双端队列中的项目,因此不得不使用双端队列。我要做的是:将roatate()移至给定的项目,将其弹出,修改,推回去,然后将它旋转()返回其原始位置。除非找到在队列中实现修改项目的方法,否则我必须坚持Deque

python thread-safety deque
4个回答
17
投票

双端队列是线程安全的(http://docs.python.org/library/collections.html#deque-objects),用于从相反侧追加和弹出。 Beneath here,文档只提到append()和popleft()是线程安全的。

[队列本身有线程安全的实现。因此,除非有一些特殊要求,否则应使用它。


4
投票

有关信息,有Python票证引用了双端队列线程安全(https://bugs.python.org/issue15329)。

标题“阐明哪些双端队列方法是线程安全的,底线是:

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

无论如何,如果您不确定100%的可靠性,而宁愿选择可靠性而不是性能,只需为print self.q.popleft()self.q.append(val)放一个类似的锁;)


1
投票

这里是Deque作者。

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

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

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

def run(self):
    while True:
        try:
            print self.q.popleft()
        except IndexError:
            pass
        time.sleep(1)

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.