簡體   English   中英

python字典是線程安全的嗎?

[英]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的標准化語義保證了這種行為,因此語言的不同實現都應該保留它。

這兩個概念完全不同。 線程安全意味着兩個線程不能同時修改同一個對象,從而使系統處於不一致狀態。

也就是說,在迭代它時不能修改字典。 請參閱文檔。

在迭代期間不應該改變字典p。 在迭代字典時修改鍵的值是安全的(因為Python 2.1),但只要鍵組沒有改變就可以。

如果您嘗試迭代迭代之間已更改大小的字典,則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.

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