2013-05-21 14 views
11

ब्लॉक नहीं करता मैं std::mutexक्यों एक एसटीडी ताला लगा :: म्युटेक्स धागा

int main() { 
    mutex m; 
    m.lock(); 
    m.lock(); // expect to block the thread 
} 

की मेरी समझ का परीक्षण करने के लिए निम्न कोड लिखा था और फिर मैं एक system_error: device or resource busy मिला है। क्या थ्रेड को अवरुद्ध करने वाला दूसरा m.lock() नहीं है?

+2

केवल एक धागा है, इसे अवरुद्ध करने के लिए उपयोगी क्यों होगा? – stijn

+0

अन्य धागे अवरुद्ध होंगे; म्यूटेक्स-मालिक चलने की कोई गारंटी नहीं है (और वास्तव में यह संस्करण एक त्रुटि उत्पन्न करता है।) – dlev

+2

यदि उस दूसरे कॉल ने धागे को अवरुद्ध कर दिया है, तो थ्रेड को कैसे अनवरोधित किया जाएगा? –

उत्तर

12
std::mutex से

:

एक कॉलिंग धागा म्युटेक्स लॉक या try_lock बुला से पहले ही नहीं होना चाहिए।

और std::mutex::lock से:

ताला एक धागा है कि पहले से ही म्युटेक्स मालिक द्वारा कहा जाता है, तो प्रोग्राम गतिरोध सकता है। वैकल्पिक रूप से, यदि कोई कार्यान्वयन डेडलॉक का पता लगा सकता है, तो संसाधन_deadlock_would_occur त्रुटि स्थिति देखी जा सकती है।

और अपवाद खंड:

फेंकता std :: system_error जब त्रुटियां होती हैं अंतर्निहित ऑपरेटिंग सिस्टम है कि इसके विनिर्देशों को पूरा करने से रोका जा सके ताला से त्रुटियों भी शामिल है। किसी भी अपवाद को फेंकने के मामले में म्यूटेक्स लॉक नहीं है।

इसलिए यह धागे को अवरुद्ध नहीं करना चाहिए। आपके प्लेटफ़ॉर्म पर, कार्यान्वयन यह पता लगाने में सक्षम प्रतीत होता है कि थ्रेड पहले से ही लॉक का स्वामी है और अपवाद उठाता है। यह वर्णन में संकेत के अनुसार अन्य प्लेटफार्मों पर नहीं हो सकता है।

2

(std::mutex प्रश्न में उल्लेख किया गया था नहीं जब मैं इस जवाब लिखा।)

यह आप का उपयोग कर रहे म्युटेक्स पुस्तकालय और म्युटेक्स प्रकार पर निर्भर करता है - आप हमें नहीं बताया है। कुछ सिस्टम एक "रिकर्सिव म्यूटेक्स" प्रदान करते हैं जिसे इस तरह के कई बार कहा जाता है, यदि यह एक ही धागे से होता है (तो आपके पास किसी अन्य थ्रेड को लॉक करने से पहले अनलॉक की मिलान संख्या होनी चाहिए), अन्य पुस्तकालय इसे एक त्रुटि मानते हैं और कृपापूर्वक विफल हो सकता है (जैसा कि आपके पास है) या अपरिभाषित व्यवहार है।

+0

std mutex रिकर्सिव नहीं है – NoSenseEtAl

+0

भले ही यह रिकर्सिव हो, यह अवरुद्ध नहीं होगा। एक पुनरावर्ती म्यूटेक्स दूसरी बार ताला लगाता है और 2 अनलॉक की प्रतीक्षा करता है। हालांकि यह एक दूसरे धागे को अवरुद्ध करेगा। –

+1

लाइब्रेरी सी ++ 11 मानक लाइब्रेरी है, और म्यूटेक्स प्रकार 'std :: mutex' है। यह एक पुनरावर्ती म्यूटेक्स नहीं है; जिसे 'std :: recursive_mutex' कहा जाता है। और यहां व्यवहार पुनरावर्ती नहीं है; दूसरी लॉक प्राप्त करने का प्रयास करते समय यह एक त्रुटि दे रहा है। –

8

दूसरा m.lock() धागा को अवरुद्ध करने वाला नहीं है?

नहीं, यह अपरिभाषित व्यवहार देता है। दूसरा m.lock() टूट जाता है इस आवश्यकता:

सी ++ 11 30.4.1.2/7 आवश्यक है: तो मीटर प्रकार std::mutex या std::timed_mutex की है, बुला धागा म्युटेक्स स्वामी नहीं है।

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

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