चलो देखते हैं:
>>> x = 1
>>> y = 2
>>> def swap_xy():
... global x, y
... (x, y) = (y, x)
...
>>> dis.dis(swap_xy)
3 0 LOAD_GLOBAL 0 (y)
3 LOAD_GLOBAL 1 (x)
6 ROT_TWO
7 STORE_GLOBAL 1 (x)
10 STORE_GLOBAL 0 (y)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
यह है कि वे परमाणु कर रहे हैं प्रकट नहीं होता है: x और y के मूल्यों के बीच एक और धागा द्वारा बदला जा सकता है LOAD_GLOBAL
बाइटकोड, ROT_TWO
से पहले या उसके बाद, और STORE_GLOBAL
बाइटकोड के बीच।
यदि आप परमाणु रूप से दो चर को स्वैप करना चाहते हैं, तो आपको लॉक या म्यूटेक्स की आवश्यकता होगी।
उन इच्छा अनुभवजन्य सबूत के लिए:
>>> def swap_xy_repeatedly():
... while 1:
... swap_xy()
... if x == y:
... # If all swaps are atomic, there will never be a time when x == y.
... # (of course, this depends on "if x == y" being atomic, which it isn't;
... # but if "if x == y" isn't atomic, what hope have we for the more complex
... # "x, y = y, x"?)
... print 'non-atomic swap detected'
... break
...
>>> t1 = threading.Thread(target=swap_xy_repeatedly)
>>> t2 = threading.Thread(target=swap_xy_repeatedly)
>>> t1.start()
>>> t2.start()
>>> non-atomic swap detected
क्यों? जीआईएल? Disassembly परमाणुता का सुझाव नहीं है (@ jemfinch का जवाब देखें)। – kennytm
(बीटीडब्लू, उपर्युक्त टिप्पणी * एक * उदारवादी प्रश्न नहीं है।) – kennytm
@ केनी: यह मेरे हिस्से की गलतफहमी थी क्योंकि कम स्तर पर अनपॅकिंग कैसे काम करती थी। – voyager