你如何使这个Python字典线程安全?

时间:2011-12-13 10:33:07

标签: python multithreading

我在Python中运行了一个Web服务器。服务器是私有的,所以我只希望大约20个用户连接到它。服务器是多线程的(目前有8个核心,所以我想到了8个线程)。

当请求进入时,我能够识别用户。在某些查询中,我需要更新表单用户名 - >的简单dictionary布尔即可。我怎么能让这一个线程安全?

5 个答案:

答案 0 :(得分:10)

您需要创建一个全局锁定对象。

lock = threading.Lock()

然后围绕每个字典访问获取并释放锁。最简单的方法是使用新的(ish)with syntax

with lock:
    dict[key] = value

答案 1 :(得分:6)

如果你需要一个锁(以避免Joonas描述的竞争条件),并且仍然坚持使用Python 2.4,

import threading
lock = threading.Lock()

shared_dict = {}

def do_thing(user, value):
    lock.acquire()
    try:
        shared_dict[user] = value
    finally:
        # Always called, even if exception is raised in try block
        lock.release()

答案 2 :(得分:4)

您可能需要也可能不需要使用锁定,具体取决于Boolean的更新方式。

如果Boolean 的值不依赖于其先前的值,则不需要锁定:编写和读取Python字典本身就是线程安全的(除了: writing while iterating is not allowed - 但是单线程中也不允许这样做。内存可见性类似于在某些语言中使用volatile所实现的内容。

“读取 - 修改 - 写入”序列本质上不是线程安全的,导致竞争条件。如果Boolean 的值依赖于其先前的值,则必须使用锁,否则线程A可能首先读取该值,然后线程B可以更改它,并且那么A会根据过时的价值再次改变它。

答案 3 :(得分:2)

在更新字典之前使用threading.LOCK.acquire()并在完成更新后使用threading.LOCK.release()。

答案 4 :(得分:0)

您不需要将字典锁定到此操作,因为此操作是原子操作,GIL会为您解决此问题。除非你有像read-change-write这样的操作,否则不用担心。