2009-11-30 7 views
11

पायथन में थ्रेडिंग मॉड्यूल दो प्रकार के ताले प्रदान करता है: एक आम लॉक और एक पुनर्विक्रय लॉक। मुझे ऐसा लगता है कि अगर मुझे लॉक की ज़रूरत है, तो मुझे हमेशा लॉक पर आरएलॉक पसंद करना चाहिए; मुख्य रूप से डेडलॉक स्थितियों को रोकने के लिए।क्या लॉक पर एक समझदार डिफ़ॉल्ट RLock है?

कि इसके अलावा, मैं दो अंक देखते हैं, जब एक ताला एक RLock से अधिक पसंद करते हैं:

  • RLock एक और अधिक जटिल आंतरिक संरचना है और इसलिए खराब प्रदर्शन हो सकता है।
  • किसी कारण से, मैं लॉक के माध्यम से एक थ्रेड को रिकर्स करना रोकना चाहता हूं।

क्या मेरा तर्क सही है? क्या आप अन्य पहलुओं को इंगित कर सकते हैं?

+1

# 2 एक अच्छा कारण होने की संभावना नहीं है; एकमात्र मामला जहां यह गारंटीकृत डेडलॉक नहीं है, यदि रिकर्सन गैर-अवरुद्ध हो जाता है और इसमें कुछ उचित कार्यवाही होती है जब यह सत्यापित नहीं कर पाती है कि यह लॉक रखती है। और # 1 पायथन 3.2+ पर लागू नहीं होता है। 'लॉक' को प्राथमिकता देने का एक वैध कारण तब होता है जब लॉक को इसे प्राप्त करने वाले किसी भिन्न थ्रेड में रिलीज़ किया जाना चाहिए। – ShadowRanger

उत्तर

10

दो अंक:

  • आधिकारिक तौर पर जारी किया गया अजगर संस्करणों (2.4, 2.5 ... ऊपर 3.1) में, एक RLock, एक ताला तुलना में बहुत धीमी है, क्योंकि ताले सी और पायथन में RLocks (में लागू किया जाता है इस 3.2 में बदल जाएगा)
  • एक लॉक किसी भी धागे से जारी किया जा सकता (जरूरी नहीं धागा जो अधिग्रहण() यह d), एक RLock एक ही धागा है जो इसे

हासिल कर ली द्वारा जारी किया जाना है, जबकि निचली पंक्ति, मैं केवल आरएलॉक का उपयोग करने का सुझाव दूंगा यदि यह आपके द्वारा किए गए अर्थशास्त्र से मेल खाता है खोज रहे हैं, अन्यथा डिफ़ॉल्ट रूप से ताले से चिपके रहते हैं।

+1

उसने कहा, 'आरएलॉक कोड को सरल बना सकता है। यदि दो विधियां हैं जिन्हें दोनों को लॉक रखने की आवश्यकता है, और एक दूसरे को कॉल करता है, तो सादा 'लॉक' के लिए आर्किटेक्चरिंग के लिए आपको "आंतरिक" विधि को अनलॉक यूटिलिटी में विभाजित करने की आवश्यकता होती है, जिसमें सार्वजनिक नाम लॉकिंग और आंतरिक विधि को कॉल किया जाता है, जबकि "बाहरी" विधि अनलॉक उपयोगिता को सीधे कॉल करती है। और जब भी आप इस फॉर्म के कोड पुन: उपयोग में संलग्न होते हैं तो आपको यह करने की ज़रूरत है। इसके अलावा, 'आरएलॉक' एक थ्रेड में चुपचाप लॉक करने और दूसरे में अनलॉक करने का जोखिम हटा देता है (यह लॉक को लागू करता है और उसी थ्रेड से अनलॉक करता है); सामान्य मामले में त्रुटियों को रोकता है। – ShadowRanger

+0

3.1 और उससे नीचे के प्रदर्शन हिट को देखते हुए, मैं आमतौर पर व्यावहारिक कारणों से 'लॉक' की सिफारिश कर सकता था, लेकिन 3.2+ में, 'आरएलॉक' उपयोग करने के लिए कम जटिल है, सामान्य त्रुटियों को रोकता है, और यह उतना ही कुशल है; आप वास्तव में केवल 'लॉक' का उपयोग करते हैं जब आपको 'लॉक' विशिष्ट विशेषताओं की आवश्यकता होती है (उदाहरण के लिए क्रॉस-थ्रेड अधिग्रहण/रिलीज, इसे वेटर्स के लिए बाधा के रूप में उपयोग करना; वेटर 'लॉक' बनाता है, 'इसे प्राप्त करने के बाद, एक सूची में जोड़ता है ताले का इंतजार करें, 'फिर से अधिग्रहण करें, अवरुद्ध करें; फिर' रिलीज 'को' वेटर 'जारी रखने दें, बेशक, मैं बस वर्णन कर रहा हूं कि' कंडीशन 'आपके लिए क्या करती है, इसलिए इसे स्वयं न करें) । – ShadowRanger

3

आम तौर पर आपको अपने कोड को इस तरह की संरचना करना चाहिए कि आपको कभी भी सामान्य ऑपरेशन में लॉक करने की आवश्यकता नहीं है (मूल रूप से यह आपको संरक्षित डेटास्ट्रक्चर के चारों ओर ताले का उपयोग करने के लिए मजबूर करता है)। इसलिए आप एक असंगत रिकर्सिव लॉकिंग पकड़ना चाहते हैं।

+0

आपका उत्तर तात्पर्य है कि [उदाहरण] (http://effbot.org/zone/thread-synchronization.htm#re-entrant-locks-rlock) पहले स्थान पर 'RLock' को प्रेरित करने के लिए उपयोग किया जाता है, इसका उपयोग करके पुनः लिखा जाना चाहिए कड़े ताले, जिस बिंदु पर इसे 'आरएलॉक' की आवश्यकता नहीं होगी। क्या आप सहमत हैं? और यदि हां, तो एक अच्छा उदाहरण क्या है जो 'आरएलॉक' की आवश्यकता को प्रेरित करता है? – max

संबंधित मुद्दे