【问题标题】:Python Dictionaries and Threading ConcurrencyPython 字典和线程并发
【发布时间】:2013-08-01 23:54:11
【问题描述】:

我在 python 3 中使用非阻塞异步线程 websockets 协议(Tornado)。我在全局级别非常保守地使用字典,但它可以由任意数量的线程更新(基本上当一个新的用户连接,他们的套接字通过字典映射到一个对象)。我已经制作了一个基本的系统来处理并发......但这不是任何官方方法。由于套接字是唯一的,我认为人们尝试同时为同一个套接字分配值应该没有任何问题,但我想知道是否有规模,可能还有另一个问题,例如尝试获取调整大小时字典中的内容。作为参考,这是我想出的“并发修复”。

class Routing_Table:

    def set(self, key, value):
        self.blocked = self.blocked + 1
        self.table[key] = value
        self.blocked = self.blocked - 1

    def get(self, key):
        while(self.blocked > 0):
            pass
        return self.table[key]

    def __init__(self):
        self.table = {}
        self.blocked = 0

编辑:另外,你认为我应该添加一个类似于设置删除条目的方法吗?

【问题讨论】:

  • 您正在尝试重新发明锁、RLock 和信号量。您可以在 python 文档中查找这些术语。
  • 你认为你为什么需要这个?不是龙卷风事件驱动的吗?当事件触发时调用处理程序,处理程序运行直到它触发,然后程序可以处理另一个事件。
  • @Hyperboreus -- 我对锁了解不多,但我知道我不能使用它们,因为 Tornado 是非阻塞的。
  • @SwiftCore:不,CPython 是最常见的 Python 解释器。 Cython 是一组用于构建 CPython 扩展模块的工具。
  • @SwiftCore,我同意abamert,但你也可以使用Cython编译python代码,据我了解。

标签: python tornado


【解决方案1】:

如果你想以线程安全的方式做任何事情,基本思想是:

class ConcurrentThingy:
    def __init__ (self):
        self.lock = Lock () # or RLock () if you want it to be reentrant    

    def concurrentlyAccessedMethod (self, *args, **kwargs):
        with self.lock: doMeanStuff ()

您的课程可能如下所示:

class Routing_Table:
    def set (self, key, value):
        with self.lock: self.table[key] = value

    def get(self, key):
        with self.lock: return self.table[key]

    def __init__(self):
        self.table = {}
        self.lock = Lock ()

【讨论】:

  • 访问和设置字典项不能保证是原子的。 STORE_SUBSCR 可能只有一个操作码,但它可能调用任意函数——事实上,它必须这样做,以便散列您的密钥。
  • 很抱歉,我还没有上操作系统课程(我一完成算法就会参加 OCW 课程),但我认为为了锁定你必须控制线程?所以如果 Tornado 正在制作线程,那么我不能这样做吗?如果没有,我会这样做,因为它比自己编写代码更干净。
  • @SwiftCore:如果 Tornado 正在制作线程,你可以这样做……只是你最终可能会打破 Tornado 所做的一些假设。
  • @SwiftCore 而@hyperboreus 没有提到的是,您应该始终使用with <lock name>,以防万一出现异常,锁仍会释放
  • @SwiftCore 请看我的编辑。 Eiyiroü von Kauyf, abarnert 希望我提供的补丁类确实是thread sage,否则请指正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多