在Python中阻止dict?

时间:2014-10-27 11:14:00

标签: python multithreading dictionary

Python中的数据结构是否类似于阻塞字典?此数据结构必须满足以下要求:

  • 必须随机访问并允许修改/删除任何元素(不仅仅是第一个或最后一个)
  • 它必须有一个阻塞的get()和put()
  • 必须是线程安全的

我会使用队列,但是虽然阻塞和线程安全,但它不是随机可访问的。 dict也没有阻塞(就我的Python知识而言)。 例如,考虑一个生产者线程将键 - 值对添加到这样的数据结构(如果已经存在,则更新现有键的值 - 这是队列不会切割它的地方),以及阻止get()的工作者并在这些键值对可用时使用它们。 非常感谢!

编辑: 让我们假设生产者轮询CI服​​务器并获得项目状态对。它生成项目状态的差异,并将它们放在上述数据结构中。工作人员获取这些项目状态更新,并在屏幕上逐个显示它们。

class Producer:
  def generateProjectStatusChanges():
    ...
  def updateSuperAwesomeDataStructure(changes):
    for (proj, stat) in changes:
      #queue won't do cause the update could take place in the middle of the queue
      #hence the dict behavior
      superAwesomeDS.putOrUpdate(proj, stat) 
  def watchForUpdates():
     changes = generateProjectStatusChanges()
     updateSuperAwesomeDataStructure(changes)
     time.sleep(self.interval)

class Worker:
  def blockingNotifyAnimation():
    ...
  def watchForUpdates():
    while true:
      proj, stat = superAwesomeDS.getFirstPair() #or any pair really
      blockingNotifyAnimation(proj, stat)

1 个答案:

答案 0 :(得分:2)

以下几行中的某些内容应该可以解决问题(未经测试):

class UpdatableBlockingQueue(object):

  def __init__(self):
    self.queue = {}
    self.cv = threading.Condition()

  def put(self, key, value):
    with self.cv:
      self.queue[key] = value
      self.cv.notify()

  def pop(self):
    with self.cv:
      while not self.queue:
        self.cv.wait()
      return self.queue.popitem()

它使用字典作为队列,并使用条件变量来序列化线程之间的访问和信令。