序列拆包原子?
回答
這是一個操作;應用了左手分配前右側表達式求值:
>>> a, b = 10, 20
>>> a, b
(10, 20)
>>> b, a = a, b
>>> a, b
(20, 10)
>>> a, b = a*b, a/b
>>> a, b
(200, 2)
或者,如果你談論的多線程環境,然後分配是不原子;解釋器的計算結果與單個操作碼的元組分配,但使用獨立的操作碼,以便然後存儲結果到每個受影響的變量:
>>> def t(self): a,b=20,20
...
>>> dis.dis(t)
1 0 LOAD_CONST 2 ((20, 20))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 1 (a)
9 STORE_FAST 2 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
然而,正常賦值是始終將是至少兩個操作碼(一個用於右手錶達,一個用於存儲結果),所以在一般分配新建分配FY蟒不是原子。序列拆包也不例外。
我認爲這不是「原子」表達。即使'j = i + 1'在高級語言中也不是原子。我有Python中的信號量......我誤解了這個問題? –
這並不能確定它是原子的。問題是'a'和'b'是否在併發環境中以原子方式分配它們的值(即,作爲不可分割的操作)。我不相信他們是;也就是說,如果'(A,B)'應該與值落得'(200,2)'中的最後一步,另一個線程可能會看到'(200,10)'或'(20,2)'。 –
我誤解了這個問題(或者說,我選擇用關於元組分配的更常見的問題來解釋非常稀疏的問題)。我已經更新它以包含線程安全信息。 –
絕對不是在多線程環境中的原子,使用以下腳本進行了測試:
import threading
a, b = 10, 10
finished = False
def thr():
global finished
while True:
# if sequence unpacking and assignment is atomic then (a, b) will always
# be either (10, 10) or (20, 20). Could also just check for a != b
if (a, b) in [(10, 20), (20, 10)]:
print('Not atomic')
finished = True
break
t = threading.Thread(target=thr)
t.start()
while True:
for i in range(1000000):
a, b = 20, 20
a, b = 10, 10
if finished:
t.join()
break
使用CPython的2.6,2.7和3.2的測試。在每個版本上,這個腳本都打印出「不是原子的」,並在一秒鐘內退出。
你讓我重新檢查操作碼;解包是一個,但是接下來有兩個STORE_FAST操作碼,每個操作碼對應一個受影響的變量。另一個線程有很多機會分配不同的東西。 –
- 1. 拆開序列
- 2. 拆分序列
- 3. 在拆分序列
- 4. 製作SQL語句的序列原子
- 5. 將原子添加到列表序言
- 6. 使用Hazelcast的原子序列
- 7. 序言:轉換原子新的原子
- 8. 原子包重寫OSX keybind
- 9. Maven原型:子包名
- 10. 原子包列表沒有禁用的列表
- 11. 將列表拆分成已排序的子列表
- 12. 最長的公共子序列(還原序列)
- 13. 拆分包含列電子郵件地址
- 14. 拆包
- 15. UVM:將序列拆分到不同的子順序器上
- 16. ERlANG - 將列表拆分成子列表
- 17. 拆分陣列爲多子陣列
- 18. ERLANG - 將列表拆分成子列表
- 19. 拆分列表到子列表
- 20. IPython的有序列拆封
- 21. 將列表的子列表拆分爲其他子列表
- 22. 使用所有因子(包括缺失因子)合併拆分xt的列表
- 23. 格式字符串拆包列表
- 24. 「拆散」包含列表爲多行
- 25. 元組拆包列表建設(python3)
- 26. 拆包列表理解內部分裂
- 27. 拆下包裝
- 28. 元組拆包
- 29. 異步原子陣列
- 30. CUDA原子操作列表
我的印象是,你也許什麼是*一般*通過原子在軟件開發中理解誤區下。你在說這裏的線程安全嗎,還是你想知道'a = c'會在'b = d'之前執行? –
@MartijnPieters - 如果OP想知道關於後者,OP會很困惑,爲什麼像'(A,B)=(B,A)'會工作交換價值。它必須是關於線程安全的問題。 –
@TedHopp:這個問題太模糊了,不能稱之爲,根據我的經驗,tuple拆包會導致大量混淆。 –