我在Python
中运行了一个Web服务器。服务器是私有的,所以我只希望大约20个用户连接到它。服务器是多线程的(目前有8个核心,所以我想到了8个线程)。
当请求进入时,我能够识别用户。在某些查询中,我需要更新表单用户名 - >的简单dictionary
布尔即可。我怎么能让这一个线程安全?
答案 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这样的操作,否则不用担心。