python:如果key不在字典中添加密钥。防止多线程的竞争条件

问题描述 投票:1回答:2

我正在编程一个电报机器人,其中更多的线程处理每个更新异步。我硬编码一个空字典,当机器人运行时,多个线程写入和读取它。

最常见的操作是:

if key not in dict:
    dict[key] = value
else:
    dict[key].append(another_value)

问题是,当一个线程检查dict中是否存在密钥,而且可能不是,另一个线程在其中写入了密钥。

所以基本上我必须摆脱这种竞争条件。

我需要快速的解决方案。在网上搜索我找到了关于threading.Lock()的答案。这些答案大约有10年的历史。我想知道现在它仍然是一个很好的解决方案,或者可能还有一些新的库

python multithreading dictionary race-condition
2个回答
4
投票

您可以使用defaultdict,或者,如果您想使用常规字典,可以使用setdefault()方法。

使用defaultdict

from collections import defaultdict
mydict = defaultdict(list)    # new key is initialized with an empty list
mydict[key].append(value)     # so it is always safe to append

使用setdefault()

mydict = {}
mydict.setdefault(key, []).append(value)

要么是线程安全的,IIRC,即使它们看起来不那样:方法实现在C中,因此不能被Python代码中断。因此,例如,永远不可能有两个setdefault()方法在字面上同时执行并导致竞争条件。

通常defaultdict是首选,因为它更高性能,仅在需要时生成空列表,并且生成的代码更简单。如果字典中的某些键可能具有非列表值,则setdefault()版本可能会更好。


0
投票

Python的dicts对于单个操作是安全的,但是多个操作不是。您目前正在做的是多个操作。锁很好,通常是处理这个问题的标准方法。

看一看这里有关Python的线程安全的一些细节。

http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm

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