2012-03-28 176 views
2

我知道python中的內置集合類型通常不是線程安全的,但this回答稱從兩個競爭線程中調用pop()是安全的。當然,你可能會遇到異常,但是你的數據沒有被破壞。我似乎無法找到驗證此聲明的文檔。這是真的嗎?請記錄文件!在Python中,是set.pop()線程安全嗎?

+0

看看Python源代碼,'set'對象只是帶有一些方便的方法的字典。 – Blender 2012-03-28 15:49:58

+0

我認爲[你正在尋找的答案](http://stackoverflow.com/a/2227210/1132524)是你指出的那個。閱讀評論並查看[GIL](http://wiki.python.org/moin/GlobalInterpreterLock)是什麼。 – 2012-03-28 15:50:56

+0

同樣的問題你鏈接說,可變類型不是線程安全的:http://stackoverflow.com/a/2227220/104847你必須實現鎖定機制,所以你沒有競爭條件。 – Ale 2012-03-28 15:53:51

回答

8

如果你看set.pop method in the CPython source你會發現它不釋放GIL。

這意味着只有一個set.pop將在CPython過程中一次發生。

由於set.pop checks if the set is empty,您不能通過嘗試從空集彈出而導致除IndexError之外的任何內容。

所以不,你不能通過使用CPython在多個線程中彈出集合來破壞數據。

+0

接受這個答案,因爲它解決了我眼前的問題。請注意fffuuuutttuuuurree的讀者:請注意@Niklas(以上)的評論。 – 2012-03-30 15:27:18

0

我相信Set「pop」操作是線程安全的,因爲它是原子的,因爲兩個線程將無法彈出相同的值。

例如,如果另一個線程遍歷該集合,我不會依賴它的行爲。

我也找不到任何具體的文檔,只是一些指向這個方向的話題。 Python官方文檔確實會受益於這種信息。

+0

查看我答案中的源代碼鏈接。在CPython中,'set.next'和'set.pop'不能同時發生,所以最糟糕的情況是如果你從序列中刪除一個項目,同時在'for '循環 - 你跳過一個項目。 – agf 2012-03-28 17:08:24