我有一个 Web 服务器在
Python
中运行。该服务器是私有的,所以我预计只有大约 20 个用户连接到它。服务器是多线程的(目前有 8 个核心,所以我猜是 8 个线程)。
当请求进来时,我能够识别用户。在某些查询中,我需要更新一个简单的
dictionary
,其形式为 username -> Boolean。我怎样才能使这个线程安全?
您可能需要也可能不需要使用锁,具体取决于
Boolean
的更新方式。
如果
Boolean
不 的值取决于其先前的值,则不需要锁:写入和读取 Python 字典本身是线程安全的(除了:不允许在迭代时写入 -但这在单线程中也是不允许的)。内存可见性类似于在某些语言中使用 volatile
所实现的效果。
本质上不是线程安全的是“读取-修改-写入”序列,从而导致竞争条件。如果
Boolean
does 的值取决于它之前的值,那么你必须使用锁,因为否则线程 A 可以先读取该值,然后线程 B 可以更改它,然后 A 会再次更改它,基于过时的值开始。
如果您需要锁(以避免 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()
在更新字典之前使用 threading.LOCK.acquire(),并在更新完成后使用 threading.LOCK.release()。
您不需要将字典锁定到此操作,因为此操作是原子操作,GIL 会为您处理此操作。除非您有读-更改-写之类的操作,否则不用担心。