-1
A
回答
3
不,你的代碼不是線程安全的,因爲使用的字典值+=
增量賦值需要3個操作碼來執行:
>>> dis.dis(compile("dic['key'] += 1", '', 'exec'))
1 0 LOAD_NAME 0 (dic)
3 LOAD_CONST 0 ('key')
6 DUP_TOPX 2
9 BINARY_SUBSCR
10 LOAD_CONST 1 (1)
13 INPLACE_ADD
14 ROT_THREE
15 STORE_SUBSCR
16 LOAD_CONST 2 (None)
19 RETURN_VALUE
在9位的操作碼,BINARY_SUBSCR
檢索從當前值詞典。操作碼9和15之間的任何位置(其中STORE_SUBSCR
將數值放回),可能會發生線程切換,並且不同的線程可能已更新字典。
1
Python的內置結構對於單個操作是線程安全的。 GIL(全球解釋器鎖)負責照顧。但是很難看到一個聲明變成了更多的操作。
加把鎖會給你安心:
def somefunc(someparam):
if someparam:
with lock:
dic['key'] +=1
+1
謝謝,我知道我可以使用鎖。問題是如果該特定操作是線程安全的,則http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm – oshaiken
謝謝!這就是我需要知道的,我知道dic是線程安全的,但我不確定+ @ – oshaiken
@OlzhasShaikenov:字典不一定是線程安全的;如果要存儲的對象是定義了__hash__和/或__eq__的Python定義的類的實例,則在存儲對象和線程上下文切換時,解釋器將執行這些方法。 –
這並不符合我對GIL及其目的所瞭解的一般閱讀理解。它的目的是讓單個操作碼線程安全嗎?在這方面有什麼具體的我可以搜索以瞭解GIL? – roganjosh