[英]python dictionary is thread safe?
有人說python字典是線程安全的。 這是否意味着我可以或不可以在迭代時修改字典中的項目?
其他答案已經正確解決了你的實際問題:
這是否意味着我可以或不可以在迭代它時修改字典中的項目?
解釋說,線程安全無關這個問題, 在任何情況下,不,你不能在遍歷它修改的字典。
但是,您的問題標題是關於線程安全的,您可以從以下開始:
有人說python字典是線程安全的
我不知道“有些人”是誰,但是,如果他們確實說(而不是你誤解了他們所說的狀態;-)沒有嚴格的資格,他們就錯了。
一些操作,那些不改變鍵組在快譯通,恰好是線程安全的在當前的CPython實現-但你不應該指望的是,除非你嚴格控制Python版本下,你的代碼將運行,因為Python的語言規范不能保證這樣的線程安全性,因此其他實現(包括CPython的未來版本)可能不會提供它。
如果每個線程只是“讀取”dict(索引它,循環它等),並且沒有線程對它執行任何賦值或刪除,那么這種情況在當前的CPython實現中是安全的。 實際上,如果某個線程為已經存在的鍵分配了一個新值,那么它也是線程安全的(其他線程可能會看到該鍵的前一個值,或者下一個,具體取決於線程的定時方式,但是在當前的CPython實現中,不會出現崩潰,沒有死鎖,也不會出現瘋狂的價值觀。
然而,諸如d[k] += 1
(假設k先前存在,並且其值為數字)的操作不正確地說是線程安全的(比其他情況+=
!更多)因為它可以被視為d[k] = d[k] + 1
- 可能會發生競爭條件中的兩個線程都讀取d[k]
的舊值,然后將其遞增1,並將相同的新值存儲在槽中。所以總體效果是只增加一個,而不是通常會增加兩個。
回到你的另一個問題......“只讀”字典, 並為字典中已經存在的鍵指定新值,這也是你可以在循環體中進行迭代的事情 - 你可以不改變dict中的鍵組(不能添加任何鍵,也不能刪除任何鍵),但允許為現有鍵設置新值的具體操作。 在這種情況下允許的操作確實包括在線程情況下會出現問題的+=
。 例如:
>>> d = dict.fromkeys(range(5), 0)
>>> for k in d: d[k] += 1
...
>>> d
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1}
Python的標准化語義保證了這種行為,因此語言的不同實現都應該保留它。
如果您嘗試迭代迭代之間已更改大小的字典,則python的最新版本將引發異常。
>>> d={'one':1, 'two':2}
>>> for x in d:
... d['three']=3
... print x
...
two
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
請注意,您不需要使用線程來查看此內容
如果同時在另一個線程中添加或刪除元素,則無法迭代字典。 您可以獲得“RuntimeError:迭代期間字典更改大小”或“KeyError”錯誤。
查看實時示例 ,您可以使用它。
是的,您可以迭代,更改元素的值,在不同的線程中同時獲取它的元素而沒有異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.