2009-03-13 15 views
8

क्या यह अधिक नहीं होगा और इनमें से केवल एक आवश्यक होगा? मैंने सी # here और here में म्यूचुअल एक्सक्लूस और लॉक के बारे में अलग-अलग पोस्ट की खोज की है और पाया है।

उदाहरण:
हमारे ऐप में, हमारे पास एक ऐसा फ़ंक्शन है जो एकाधिक पुन: कनेक्शन धागे को स्पिन करता है और इस धागे के अंदर हम Mutex और lock का उपयोग करते हैं। lock कोड के इस खंड तक पहुंच को अवरुद्ध नहीं करेगा और connect को किसी अन्य थ्रेड द्वारा अपडेट करने से रोकें?सी # में ताले और म्यूटेक्स को एक साथ इस्तेमाल किया जाना चाहिए

bool connect = false; 
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); 

try 
{ 
    lock(site) 
    { 
     if(site.ContainsKey(key)) 
     { 
     siteInfo = (SiteInfo)site[key]; 
     if(reconnectMutex.WaitOne(100, true)) 
     { 
      connect = true; 
     } 
     } 
    } 

    if (connect) 
    { 
     // Process thread logic 
    } 
} 
catch 
{} 

reconnectMutex.ReleaseMutex(); 

अधिक जानकारी:
इस में एक ASP.NET WebService एक वेब गार्डन में नहीं चल रहा है।

उत्तर

11

वह म्यूटेक्स (क्योंकि इसका नाम है) उसी मशीन पर भी किसी भी प्रक्रिया को रोक देगा, जबकि लॉक केवल उसी प्रक्रिया में अन्य धागे को रोक देगा। मैं उस कोड नमूने से नहीं देख सकता हूं कि आपको दोनों प्रकार के लॉक की आवश्यकता क्यों होगी। यह एक छोटी अवधि के लिए सरल ताला पकड़ने के लिए अच्छा अभ्यास प्रतीत होता है - लेकिन फिर अधिक भारी इंटरप्रोसेस म्यूटेक्स संभवतः लंबे समय तक (हालांकि ओवरलैपिंग) अवधि के लिए बंद कर दिया गया है! बस mutex का उपयोग करने के लिए आसान होगा। और शायद यह पता लगाने के लिए कि एक इंटरप्रोसेस लॉक वास्तव में आवश्यक है या नहीं।

वैसे, catch {} उस परिदृश्य में उपयोग करने के लिए बिल्कुल गलत बात है। आपको finally { /* release mutex */ } का उपयोग करना चाहिए। वे बहुत अलग हैं। पकड़ से यह होना चाहिए अपवाद की कहीं अधिक प्रकार निगल जाएगा, और यह भी अंत में संचालकों तो बजाय इस तरह के स्मृति भ्रष्टाचार, पहुँच उल्लंघन, आदि के रूप निम्न स्तर के अपवाद के जवाब में निष्पादित करने के लिए नेस्ट कारण होगा:

try 
{ 
    // something 
} 
catch 
{} 

// cleanup 

आप होना चाहिए:

try 
{ 
    // something 
} 
finally 
{ 
    // cleanup 
} 

और अगर वहाँ विशिष्ट अपवाद आप से ठीक हो सकता है कर रहे हैं, तो आप उन्हें पकड़ सकते थे:

try 
{ 
    // something 
} 
catch (DatabaseConfigurationError x) 
{ 
    // tell the user to configure the database properly 
} 
finally 
{ 
    // cleanup 
} 
+0

इसे मशीन-विशिष्ट होने के अनुसार नामित किया जाना चाहिए, हालांकि। –

+0

अच्छा बिंदु, मैंने आशा व्यक्त की है कि पहले वाक्य में। –

+0

क्या आप कह रहे हैं कि मुझे कैच स्टेटमेंट को खत्म करना चाहिए और अंत में इसे बदलना चाहिए? –

3

"ताला" मूल रूप से है सिर्फ एक मॉन्टोर के लिए सिंटेक्टिक चीनी। प्रवेश/बाहर निकलें। म्यूटेक्स एक बहु-प्रक्रिया लॉक है।

उनके पास बहुत अलग व्यवहार है। एक ही एप्लिकेशन या विधियों में दोनों का उपयोग करने में कुछ भी गलत नहीं है, क्योंकि वे अलग-अलग चीजों को अवरुद्ध करने के लिए डिज़ाइन किए गए हैं।

हालांकि, आपके मामले में, मुझे लगता है कि आप सेमफोर और मॉनिटर में देखकर बेहतर हो सकते हैं। ऐसा लगता है कि आपको प्रक्रियाओं में लॉक करने की आवश्यकता नहीं है, इसलिए वे शायद इस स्थिति में बेहतर विकल्प हैं।

1

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

अब साइट पर लॉक साइट को उसी प्रक्रिया में अन्य धागे द्वारा एक्सेस से सुरक्षित रखता है। अन्य तरीकों/धागे क्या कर रहे हैं इसके आधार पर यह निराशाजनक हो सकता है। अब अगर यह एकमात्र जगह है जहां साइट लॉक हो रही है तो हाँ मुझे लगता है कि यह अधिक है।

2

जैसा कि अन्य ने इंगित किया है, म्यूटेक्स प्रक्रियाओं में लॉक हो जाता है और स्थानीय लॉक (मॉनिटर) केवल उन प्रक्रियाओं को लॉक करता है जो वर्तमान प्रक्रिया के स्वामित्व में हैं। हालांकि ...

आपके द्वारा दिखाए गए कोड में एक बहुत ही गंभीर बग है।ऐसा लगता है कि आप अंत में बिना किसी शर्त के म्यूटेक्स को जारी कर रहे हैं (यानी reconnectMutex.ReleaseMutex()), लेकिन म्यूटेक्स केवल तभी प्राप्त होता है जब site.ContainsKey()true लौटाता है।

तो site.ContainsKeyfalse लौटाता है, तो म्यूटेक्स को जारी करने से ApplicationException फेंकने जा रहा है क्योंकि कॉलिंग थ्रेड में म्यूटेक्स नहीं है।

+0

धन्यवाद - मैंने इसे पोस्ट करने के बाद उस बग को पाया। मैं यह नहीं समझ सका कि ऐप क्यों बंद हो रहा था - वह समस्या थी। –

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