2009-12-15 27 views
9

मुझे पता है, मुझे पता है, मेरे संदेश का शीर्षक उत्तेजक प्रतीत हो सकता है, क्योंकि boost :: mutex purposefuly लॉक/अनलॉक का खुलासा नहीं करता है (मृत से बचने के लिए ताले)।boost :: mutex/अगर mutex लॉक किया गया है तो परीक्षण कैसे करें

हालांकि इन पहलुओं (कम से कम कहने के लिए) में बूस्ट प्रलेखन काफी कम है, इसलिए मैं पूछ रहा हूं कि कोई भी निम्नलिखित उपयोग मामले में मेरी सहायता कर सकता है या नहीं।

मान लीजिए आप एक वर्ग फू, जो है:
- एक नाशक है कि कुछ समय
पूरा करने के लिए लेता है - एक विधि है कि एक अलग धागे से पुकारा जाता है, लेकिन विनाश के दौरान कहा जाता है नहीं किया जाना चाहिए

class Foo 
{ 
public: 

    virtual ~Foo() 
    { 
    //Time consuming operations here 
    } 


    //Method called by a timer belonging to a distinct class 
    void OnTimer() 
    { 
    //Other time consuming stuff. Should not be called during destruction ! 
    } 


}; 

मैं (कोई सफलता के साथ) की कोशिश की को बढ़ावा देने के आधार पर एक संस्करण :: म्युटेक्स

//boost::mutex implementation 
class Foo 
{ 
public: 
    Foo() 
    { 
    } 

    virtual ~Foo() 
    { 
    { 
     boost::mutex::scoped_lock lock(mDisposingMutex); 
     //Time consuming operations here 
    } 
    } 


    //Method called by a timer belonging to a distinct class 
    void OnTimer() 
    { 
    { 
     //Imaginary code here: mutex::locked() method is private !!! 
     if (! mDisposingMutex.locked()) 
     return; 
    }  
    //Other time consuming stuff. Should not be called during destruction ! 
    } 

private: 
    boost::mutex mDisposingMutex; 
}; 

मैं हूँ पूरी तरह से गलत लागू करने के लिए? क्या कोई मुझे बता सकता है कि यह boost :: mutex के साथ कैसे किया जाना चाहिए?

धन्यवाद!

+0

क्यों अपनी वस्तु विलुप्त की जा रही है, जबकि एक अन्य धागा अभी भी यह करने के लिए एक सूचक है? –

+0

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

+0

@ आओन: सहमत, यह एक कोड गंध है। हालांकि मुझे अभी भी जवाब में दिलचस्पी है। @ सेह: आपकी टिप्पणी एक ही कोड गंध पर आधारित है। हालांकि, मैं encapsulation तोड़ने के बिना सीधे इसे रद्द नहीं कर सकता। –

उत्तर

5

आप नाशक शरीर में Lockable::lock() का उपयोग कर के लिए प्रतिबद्ध है, तो आप अपने OnTimer() समारोह उपयोग Lockable::try_lock() है, और आगे बढ़ना है कि समारोह सच रिटर्न केवल तभी कर सकते हैं। OnTimer() होगा OnTimer() पहले शुरू होता है, लेकिन अभी भी म्यूटेक्स को चलाने, परिष्कृत करने और रिलीज़ करने की समस्या को हल नहीं करता है, और फिर OnTimer() प्रारंभ और सफलतापूर्वक म्यूटेक्स को पकड़ने में समस्या का समाधान नहीं करता है।

ऐसा अनुक्रम अपरिभाषित व्यवहार के दायरे में होने की संभावना है, लेकिन वह अभिशाप इसे होने से नहीं रोक पाएगा। Mutex के अलावा एक राज्य ध्वज का उपयोग करना - जैसा कि मैंने उपरोक्त मेरी टिप्पणी में वर्णित किया है - जैसा कि आप इस बाद के मामले का पता लगाने और ध्वज पढ़ने से परे कुछ भी करने से OnTimer() को रोक सकते हैं। कुछ बिंदु पर, हालांकि, यह बैंड-एड्स के शीर्ष पर बैंड-एड्स लगा रहा है।

2

म्युटेक्स :: try_lock()

+0

यह गलत है अगर आप म्यूटेक्स को लॉक करते हैं। –

4

@ सेह: मैं पूरी तरह से सहमत हूं कि यह एक कोड गंध है और मुझे मूल कारण को सही (और करेंगे) करना चाहिए।

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

#include <boost/thread/mutex.hpp> 

//boost::mutex implementation 
class Foo 
{ 
public: 
    Foo() : 
    mIsDisposing(false) 
    { 
    } 

    virtual ~Foo() 
    { 
    { 
     boost::try_mutex::scoped_try_lock lock(mDisposingMutex); 
     if (! lock.locked()) 
     { 
     //Die by horrible death, or wait before trying again... 
     } 
     else 
     { 
     mIsDisposing = true; 
     } 
     //Time consuming operations here 
    } 

    } 


    //Method called by a timer belonging to a distinct class 
    void OnTimer() 
    { 
    { 
     boost::try_mutex::scoped_try_lock lock(mDisposingMutex); 
     if (! lock.locked() || mIsDisposing) 
     { 
     return;  
     } 
    }  
    //Other time consuming stuff. Should not be called during destruction ! 
    } 

private: 
    boost::try_mutex mDisposingMutex; 
    bool mIsDisposing; 
}; 
संबंधित मुद्दे