2010-04-12 14 views
30

नीचे दिए गए लिंक के संदर्भ में: http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safeएक परिवर्तनीय स्वैप पाइथन में परमाणु होने की गारंटी है?

मैं यदि निम्न में जानना चाहता था:

(x, y) = (y, x) 

CPython में परमाणु गारंटी दी जाएगी। (एक्स और वाई दोनों पायथन चर हैं)

उत्तर

54

चलो देखते हैं:

>>> 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 
4

हाँ, हाँ यह होगा।

I stand corrected

Kragen Sitaker लिखते हैं:

किसी मुहावरा

spam, eggs = eggs, spam 

का उपयोग कर एक धागा सुरक्षित स्वैप प्राप्त करने के लिए सिफारिश की है। क्या यह वास्तव में काम करता है? (...)
तो यदि यह धागा पहले LOAD_FAST
और अंतिम STORE_FAST के बीच कहीं भी नियंत्रण खो देता है, तो एक मान किसी अन्य थ्रेड
द्वारा "बी" में संग्रहीत किया जा सकता है जो तब खो जाएगा। ऐसा होने से
को रखने से कुछ भी नहीं है, है ना?

नहीं। सामान्य रूप से एक साधारण असाइनमेंट आवश्यक रूप से थ्रेड सुरक्षित असाइनमेंट करने के बाद से ऑब्जेक्ट पर विशेष विधियों का आह्वान कर सकता है, जिन्हें स्वयं को संचालन की आवश्यकता हो सकती है। उम्मीद है कि ऑब्जेक्ट आंतरिक रूप से "स्थिति" मानों को बंद कर देगा, लेकिन यह हमेशा केस नहीं है।

लेकिन क्या यह वास्तव क्योंकि मेरे मन वहाँ करने के लिए, क्या "धागा सुरक्षा" एक विशेष आवेदन में इसका मतलब है से निर्धारित है इस तरह के सुरक्षा के विवरण के किसी कई स्तर होते हैं तो यह के बारे में "धागा सुरक्षा" बात करने के लिए मुश्किल है। केवल के बारे में पाइथन दुभाषिया पर जा रहा है, आपको मुफ्त में यह है कि अंतर्निहित डेटा प्रकार आंतरिक मूल थ्रेडिंग के साथ भी भ्रष्टाचार से सुरक्षित होना चाहिए। दूसरे शब्दों में अगर दो धागे a=0xff और a=0xff00 है, एक एक या दूसरे, लेकिन नहीं गलती से 0xffff साथ के रूप में अंत कुछ अन्य भाषाओं में संभव हो सकता है अगर एक संरक्षित नहीं है जाएगा।

इसी के साथ

कहा, अजगर भी जाता तरह के एक फैशन है कि आप बिना औपचारिक लॉकिंग एक भयानक बहुत कुछ के साथ प्राप्त कर सकते हैं, यदि आप करने को तैयार हैं किनारे पर एक सा रहते हैं और है में निष्पादित उपयोग में वास्तविक ऑब्जेक्ट्स पर अंतर्निहित निर्भरताएं। सीएल में उन पंक्तियों के साथ एक सभ्य चर्चा थी।पी थोड़ी देर पहले - अन्य लोगों के बीच "क्रिटिकल अनुभाग और म्यूटेक्स" धागे के लिए groups.google.com खोजें।

व्यक्तिगत रूप से, मैं स्पष्ट रूप से किसी भी मल्टी-थ्रेडेड आवेदन में राज्य (या उपयोग इस तरह के Queue.Queue रूप का आदान प्रदान साझा जानकारी ठीक से धागे के बीच के लिए बनाया गया निर्माणों,) साझा ताला। पर मेरे दिमाग में यह है जो सड़क के रखरखाव और विकास के खिलाफ सबसे अच्छी सुरक्षा है।

- - David

+1

क्यों? जीआईएल? Disassembly परमाणुता का सुझाव नहीं है (@ jemfinch का जवाब देखें)। – kennytm

+0

(बीटीडब्लू, उपर्युक्त टिप्पणी * एक * उदारवादी प्रश्न नहीं है।) – kennytm

+0

@ केनी: यह मेरे हिस्से की गलतफहमी थी क्योंकि कम स्तर पर अनपॅकिंग कैसे काम करती थी। – voyager