2011-09-26 9 views
7

मेरे पास एक कक्षा है जिसे कई धागे द्वारा बनाया जा सकता है। लेकिन एक समारोह में कोड को संरक्षित करने की आवश्यकता है, इसलिए मैंने बूस्ट इंटरप्रोसेस म्यूटेक्स का उपयोग करने का फैसला किया। हर वर्ग बनाता है या यह की निर्माता में एक ही Mutex खोलता है:बूस्ट नाम_म्यूटेक्स और निकालें() कमांड

MyClass::MyClass() 
{ 
     boost::interprocess::named_mutex m_Lock(
       boost::interprocess::open_or_create, "myLock"); 
} 

तो अब वहाँ बिंदु है जहां महत्वपूर्ण कोड हिस्सा कहा जाता है आता है:

int MyClass::MyFunction() 
{ 
     boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(
        m_Lock, boost::interprocess::try_to_lock); 
     if(!lock) 
     { 
      return -1; 
     } 
     // else do some stuff here 
} 

समारोह के बाद साफ करने के लिए (और चाहते अपने बढ़ावा पृष्ठ पर वर्णित) मैं अपने वर्ग नाशक में निकालें आदेश का उपयोग करें:

MyClass::~MyClass() 
{ 
     boost::interprocess::named_mutex::remove("myLock"); 
} 

वास्तव में सभी के लिए इस कोड, ठीक काम करता है लेकिन इसमें भी एक चिंता का विषय रहा है:

इसे हटाने के आदेश के विवरण में कहा जाता है के रूप में:

सिस्टम से एक नामित म्युटेक्स मिटाता है। त्रुटि पर झूठी वापसी करता है। कभी फेंकता नहीं है।

तो इसका मतलब है कि निकालने का आदेश सिस्टम के बाहर म्यूटेक्स को मिटा देता है - भले ही किसी अन्य धागे ने इसे बंद कर दिया हो (मैंने पहले ही इस मामले को आजमाया है - यह अब लॉक नहीं है)। तो मेरी समस्या यह है: उदाहरण के लिए मेरे पास है 3 धागे (ए, बी और सी) - अब निम्न होता है:

  1. प्रक्रिया एक वर्ग का एक उदाहरण बनाता है, फ़ंक्शन को कॉल और यह ताले
  2. प्रक्रिया बी, वर्ग का एक उदाहरण बनाता फ़ंक्शन को कॉल लेकिन कोड का उपयोग नहीं कर सकते हैं (तो इंतजार कर रहा है जैसे)
  3. प्रक्रिया एक संरक्षित कोड के साथ खत्म और उसे अनलॉक हो जाता है
  4. प्रक्रिया बी लाभ संरक्षित कोड के लिए उपयोग और इसे
  5. प्रक्रियाओं को ताला लगाता है रों एक वर्ग के उदाहरण को हटा देता है -> निकालें आदेश में कहा जाता है
  6. प्रक्रिया सी क्लास का एक उदाहरण बनाता है, फ़ंक्शन को कॉल किया और तब से निकालने के आदेश Mutex मिट कोड का उपयोग कर सकते -> त्रुटि!

तो अब कोई कह सकता है "फिर हटाएं मत!" - क्या यह संभव है? मेरा मतलब है कि name_mutex सिस्टम को लिखता है क्योंकि मुझे संदेह है कि यह एक स्पष्ट कॉल के बिना मिटा दिया गया है, भले ही प्रोग्राम समाप्त हो। किसी को भी कुछ मदद मिली है?

+0

मैं आपके प्रश्न और "थ्रेड" और "प्रक्रियाओं" शब्दों के अंतर-उपयोग से उलझन में हूं। आप किसके साथ काम कर रहे हैं? धागे? या प्रक्रियाओं? नामांकित म्यूटिस में आम तौर पर अत्यधिक सीधी उपयोगिता होती है यदि आप केवल एक ही प्रक्रिया में बहुसंख्यक होते हैं। –

+0

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

उत्तर

6

boost docs से, remove कॉल, अनावश्यक है। named_mutex का विनाशक स्वचालित रूप से ओएस को इंगित करने वाली देखभाल करेगा कि प्रक्रिया को अब संसाधन की आवश्यकता नहीं है। सफाई के लिए विनाशक के अंतर्निहित व्यवहार पर भरोसा करने के साथ आप शायद ठीक हैं।

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

~ name_mutex();

यह * नष्ट करता है और इंगित करता है कि संसाधन का उपयोग कर कॉलिंग प्रक्रिया समाप्त हो गई है। विनाशक फ़ंक्शन इस संसाधन के लिए इस प्रक्रिया द्वारा उपयोग के लिए सिस्टम द्वारा आवंटित किसी भी सिस्टम संसाधनों को हटा देगा। संसाधन अभी भी खुले कन्स्ट्रक्टर अधिभार को बुलाकर फिर से खोला जा सकता है। सिस्टम से संसाधन को मिटाने के लिए हटाएं()।

+0

तो अगर मुझे यह सही लगता है, जब तक मैं कॉल नहीं करता() संसाधन सिस्टम में रहेगा (भले ही विनाशक कहा जाता है) - लेकिन इससे कोई फर्क नहीं पड़ता क्योंकि विनाशक ओएस को बताता है कि संसाधन " अनलॉक ", तो एक और प्रक्रिया इसे लॉक कर सकता है? क्या यह सही है ?? – Toby

+0

मैंने उनके साथ बहुत कुछ नहीं खेला है, लेकिन मुझे लगता है कि अगर म्यूटेक्स का उपयोग कर प्रक्रियाओं की संख्या शून्य हो जाती है, तो संसाधनों को मुक्त कर दिया जाएगा। मेरे लिनक्स बॉक्स पर sem_close के लिए मैन पेज कहता है: वर्णन sem_close() सेम द्वारा संदर्भित नामित सेमफोर को बंद कर देता है, इस सेमफोर को मुक्त करने के लिए सिस्टम को कॉलिंग प्रक्रिया पर आवंटित किए गए किसी भी संसाधन को अनुमति देता है। –

+10

ठीक है मैंने कल थोड़ा सा पुनर्विक्रय और परीक्षण और त्रुटि की। Mutex के लिए संसाधन साझा स्मृति (/ dev/shm /) में स्थित है। इसे बनाए जाने के बाद यह तब तक रहेगा जब तक आप हटाएं() या सिस्टम रीबूट नहीं करते। (या आप साझा स्मृति को साफ़ करने के लिए कुछ और करते हैं, उदाहरण के लिए इसे स्वयं मिटा दें)। ऑब्जेक्ट में स्वयं गीलेर के बारे में जानकारी है जो लॉक है या नहीं। जब म्यूटेक्स नष्ट हो जाता है तो यह सिर्फ अनलॉक हो जाता है लेकिन मिटा नहीं जाता है! तो एकमात्र समस्या यह हो सकती है कि कार्यक्रम कड़ी मेहनत कर रहा है और विनाशक को फोन नहीं कर सकता है और ऑब्जेक्ट लॉक रहता है। – Toby

0

आपको शायद म्यूटेक्स के लिए साझा उपयोग काउंटर की आवश्यकता है। म्यूटेक्स को विनाशक में लॉक करें, इसे घटाएं, और यदि यह कमी के बाद शून्य है, तो अभी भी लॉक किए गए म्यूटेक्स को हटा दें। आप अपनी वर्तमान दौड़ की स्थिति को उस से रोक देंगे।

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