【问题标题】:How do I store and access values from a deque where deque is being modified by another thread?如何存储和访问 deque 中的值,其中 deque 正在被另一个线程修改?
【发布时间】:2018-10-12 17:24:57
【问题描述】:

我的程序有两个线程 - 第一个用于接收字典列表形式的数据,第二个线程用于将值存储在数据库中。

buffer = collections.deque(maxlen=10)

def process_ticks(bufferarg):
   while True:
       for i in bufferarg:
            #code to insert data in a database

#this tread receives the data and dumps it into a deque with a specified length (so it can function as a circular buffer)
t1 = threading.Thread(target=socket.connect)

#this threads accesses the deque and processes the data
t2 = threading.Thread(target=process_ticks(buffer))

t1.start()
t2.start()

但是,当我运行代码时,我收到“deque is being mutated”错误。 另外,如何确保线程无限运行,但process_ticks 不会从双端队列插入相同的数据两次?

【问题讨论】:

  • 请注意,如前所述,从未启动过线程:process_ticks(buffer) 已经启动了无限循环,而不是将其推送到线程。这会阻塞主线程。它应该改为 t2 = threading.Thread(target=process_ticks, args=(buffer,))
  • @MisterMiyagi 非常感谢,伙计!

标签: python python-3.x multithreading


【解决方案1】:

在变异的过程中迭代通常是不明确的。这正是您的情况发生的情况:t1 改变缓冲区,而 t2 迭代它。

问题在于迭代假设了项目之间的强关系;突变可能会打破这一点。具体来说,deque 迭代器可能会在元素被删除时保留它,从而使对下一个元素的引用无效。

一个简单的解决方案是不使用迭代,而是一次删除一个元素:

def process_ticks(bufferarg):
    while True:
        try:
            # get and remove one item from the end of the deque
            item = bufferarg.popleft()
        except IndexError:
            # no data in buffer, try again immediately or sleep a little
            continue
        else:
            # do something with item

deque 尤其适用于此:您可以在不同的末端插入和弹出。 这还有一个额外的好处,即您永远不会两次获得相同的元素。

【讨论】:

  • 有道理,谢谢!不过,如果你不介意的话,我还有一个问题。这个过程最有效的数据结构是什么?
  • @Yuckfou deque 就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
  • 1970-01-01
相关资源
最近更新 更多