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

问题描述 投票:0回答:5

我有一个 Web 服务器在

Python
中运行。该服务器是私有的,所以我预计只有大约 20 个用户连接到它。服务器是多线程的(目前有 8 个核心,所以我猜是 8 个线程)。

当请求进来时,我能够识别用户。在某些查询中,我需要更新一个简单的

dictionary
,其形式为 username -> Boolean。我怎样才能使这个线程安全?

python multithreading
5个回答
17
投票

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

lock = threading.Lock()

然后围绕字典的每次访问获取和释放锁。最简单的方法是使用新的

with
语法

with lock:
    dict[key] = value

11
投票

您可能需要也可能不需要使用锁,具体取决于

Boolean
的更新方式。

如果

Boolean
的值取决于其先前的值,则不需要锁:写入和读取 Python 字典本身是线程安全的(除了:不允许在迭代时写入 -但这在单线程中也是不允许的)。内存可见性类似于在某些语言中使用
volatile
所实现的效果。

本质上不是线程安全的是“读取-修改-写入”序列,从而导致竞争条件。如果

Boolean
does 的值取决于它之前的值,那么你必须使用锁,因为否则线程 A 可以先读取该值,然后线程 B 可以更改它,然后 A 会再次更改它,基于过时的值开始。


9
投票

如果您需要锁(以避免 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
投票

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


-1
投票

您不需要将字典锁定到此操作,因为此操作是原子操作,GIL 会为您处理此操作。除非您有读-更改-写之类的操作,否则不用担心。

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