2010-05-20 3 views
8

में लॉक स्कोप के लिए एकाधिक चर का उपयोग कैसे करें मेरे पास ऐसी स्थिति है जहां दो लॉकर ऑब्जेक्ट्स मुक्त होने पर कोड का एक ब्लॉक निष्पादित किया जाना चाहिए।सी #

मैं वहाँ उम्मीद थी होगा कुछ की तरह:

lock(a,b) 
{ 
    // this scope is in critical region 
} 

हालांकि, वहाँ ऐसा कुछ नहीं हो रहा है। तो इसका मतलब यह है कि ऐसा करने का एकमात्र तरीका यह है:

lock(a) 
{ 
    lock(b) 
    { 
     // this scope is in critical region 
    } 
} 

क्या यह अपेक्षा के अनुसार भी काम करेगा? यद्यपि कोड संकलित करता है, लेकिन मुझे यकीन नहीं है कि यह वह हासिल करेगा जो मैं उम्मीद कर रहा हूं।

+0

इस कारण लॉक समस्याएं नहीं हो सका? एक ऑब्जेक्ट लॉक करता है, और एक और लॉक बी, अब आपके पास एक डेडलॉक होगा जहां ऑब्जेक्ट 1 बी और ऑब्जेक्ट 2 ब्लॉक के लिए प्रतीक्षा कर रहा है। मैं ताले से परिचित नहीं हूं, लेकिन यह बुरा लगता है। – Tester101

+2

यही कारण है कि लॉकिंग ऑर्डर महत्वपूर्ण है, क्योंकि अब तक के सभी उत्तरों का उल्लेख किया गया है। कभी-कभी आपको कई ताले रखने की आवश्यकता होती है, और उन मामलों में उपयोग करने के लिए मानक पैटर्न में से एक ताले पर ऑर्डर करने के लिए (कम से कम सम्मेलन के माध्यम से) लागू करना है। उदाहरण के लिए, आप कहेंगे कि जब भी आप लॉक प्राप्त करना चाहते हैं तो * आपको पहले लॉक प्राप्त करना होगा।अधिक विवाद का कारण बनता है, लेकिन deadlocks को रोकता है। जब संभव हो तो इस तरह की चीज़ से बचने के लिए हमेशा बेहतर होता है, लेकिन कभी-कभी यह आवश्यक है। – Herms

+0

@ परीक्षक 101: हाँ मुझे पता है कि अगर सही ढंग से संभाला नहीं जाता है, तो यह डेडलॉक का कारण बन जाएगा। –

उत्तर

5

मुझे उम्मीद है कि यह एक ऐसा मामला होगा जहां संभावित रूप से डेडलॉक स्थिति हो सकती है।

आम तौर पर, कोड a लॉक करने का प्रयास करेगा और फिर सफल होने पर b लॉक करने के लिए आगे बढ़ेगा। इसका मतलब है कि यह केवल कोड निष्पादित करेगा यदि यह a और b दोनों को लॉक कर सकता है। आप जो चाहते हैं वह है।

हालांकि, अगर कुछ अन्य कोड को पहले से ही b पर लॉक मिला है तो यह कोड आपकी अपेक्षा की अपेक्षा नहीं करेगा। आपको यह सुनिश्चित करने की भी आवश्यकता होगी कि हर जगह आपको a और b दोनों को लॉक करने की आवश्यकता है, आप ताले को उसी क्रम में प्राप्त करने का प्रयास करते हैं। यदि आपको पहले b मिलते हैं और फिर a आप डेडलॉक का कारण बनेंगे।

+0

असल में यह असफल नहीं होगा अगर किसी और के पास बी पर लॉक है - यह रिलीज़ होने तक प्रतीक्षा करेगा। – TomTom

+1

@ टॉमटॉम: यदि अन्य धागा सिर्फ ताले में से किसी एक तक पहुंचने का प्रयास करता है, तो हमें कोई समस्या नहीं होगी, लेकिन अगर यह ए और बी दोनों को लॉक करने की कोशिश करता है और रिवर्स ऑर्डर में, डेडलॉक के लिए अच्छा मौका है। @ChrisF: क्या वे आपके संपादन में आवश्यक बाहरी घुंघराले ब्रेसिज़ हैं, या आपने कोड को क्लीनर बनाने के लिए यह किया है? –

+0

@ गुनेर - कोड को क्लीनर बनाने और लॉक के दायरे को स्पष्ट करने का एक प्रयास है। उम्मीद है कि यह ठीक है। – ChrisF

11

दोनों पर लॉक का अनुरोध ठीक काम करना चाहिए। lock(a)a तक अवरुद्ध होगा। एक बार आपके पास लॉक हो जाने पर, lock(b) तब तक अवरुद्ध हो जाएगा जब तक आपके पास b न हो। उसके बाद आपके पास दोनों हैं।

एक चीज़ जो आपको यहां के बारे में बहुत सावधान रहने की आवश्यकता है वह आदेश है। यदि आप ऐसा करने जा रहे हैं तो सुनिश्चित करें कि हमेशाb पर लॉक प्राप्त करने से पहले a पर लॉक प्राप्त करें। अन्यथा आप खुद को एक डेडलॉक स्थिति में आसानी से पा सकते हैं।

15
lock(a) lock(b) { // this scope is in critical region } 

यह कर सकता है जब तक धागा a के लिए ताला प्राप्त कर सकते हैं अवरोधित करती हैं। फिर, उस लॉक के अधिग्रहण के साथ, यह तब तक अवरुद्ध होगा जब तक धागा b के लिए लॉक प्राप्त नहीं कर सकता। तो यह उम्मीद के रूप में काम करता है।

lock(b) lock(a) { // this scope is in critical region } 

यह एक गतिरोध स्थिति है जिसमें धागा 1 a के लिए ताला हासिल कर ली है और के लिए ताला प्राप्त करने के लिए इंतज़ार कर रहा है करने के लिए ले जा सकता है:

हालांकि, अगर आप भी इस कहीं नहीं करने के लिए सावधान रहना होगा b, और थ्रेड 2 ने b के लिए लॉक प्राप्त किया है और a के लिए लॉक प्राप्त करने का इंतजार कर रहा है।