簡體   English   中英

python:如果密鑰不在字典中,則添加密鑰。 防止多線程競爭

[英]python: if key not in dictionary add the key. preventing race conditions with multiple threads

我正在編程一個電報機器人,其中更多線程可以處理每個更新異步操作。 我用硬編碼編寫一個空字典,並且在運行bot時,有多個線程對其進行讀寫。

最常見的操作是:

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

問題在於,當線程檢查dict中是否包含key時,也許不是,另一個線程在其中寫入了key。

所以基本上我必須擺脫這種賽車狀況。

我需要一個快速的解決方案。 在網上搜索時,我發現了關於threading.Lock()答案。 這些答案大約有10年歷史了。 我想知道今天是否仍然是一個很好的解決方案,或者還有更多新的庫

您可以使用defaultdict或者,如果要使用常規dict,則可以使用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()版本可能會更好。

Python的指令對單個操作是安全的,但對多個操作則不安全。 您當前正在執行的是多項操作。 鎖很好,通常是處理此問題的標准方法。

看一下這里,以了解有關Python線程安全性的一些詳細信息。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM