2012-11-20 32 views
10

मैं सोच रहा हूँ अगर यह एक ही समय में एक से अधिक mutexes लॉक करने के लिए संभव है, जैसे:लॉकिंग कई mutexes

Mutex1.Lock(); 
{ 
    Mutex2.Lock(); 
    { 
      // Code locked by mutex 1 and 2. 
    } 
    Mutex2.Unlock(); 

    // Code locked by mutex 1. 
} 
Mutex1.Unlock(); 

यह कुछ स्थितियों के लिए बहुत उपयोगी होगा। धन्यवाद।

+2

हाँ, यह संभव है। बस सावधान रहें, उचित परिश्रम के बिना ऐसा करने से आसानी से डेडलॉक्स हो सकते हैं। –

उत्तर

12

यह संभव है लेकिन लॉकिंग का क्रम पूरे आवेदन में सुसंगत होना चाहिए अन्यथा डेडलॉक एक संभावित परिणाम है (यदि दो धागे विपरीत क्रम में ताले हासिल करते हैं तो प्रत्येक धागा दूसरे में ताले को छोड़ने के लिए इंतजार कर सकता है) ।

एक दायरे वाला लॉक का उपयोग कर सिफारिश और (उदाहरण के लिए std::mutex साथ std::lock_guard) अपवाद सुरक्षा के लिए सुविधा अनलॉक, ताले सुनिश्चित करने के लिए हमेशा जारी कर रहे हैं: अपने संकलक इन सी ++ 11 सुविधाओं को बढ़ावा देने का समर्थन नहीं करता

std::mutex mtx1; 
std::mutex mtx2; 

std::lock_guard<std::mutex> mtx1_lock(mtx1); 
{ 
    std::lock_guard<std::mutex> mtx2_lock(mtx2); 
    { 
    } 
} 

हैं boost::mutex और boost::lock_guard में समान है।

+0

मैं pthreads का उपयोग कर रहा हूं, क्या सी ++ 11 का उपयोग किये बिना मेरे प्रोग्राम को डेडलॉक्स से सुरक्षित करना संभव है? मैं pthread_mutex_lock का उपयोग कर रहा हूं और lock() और। अनलॉक() फ़ंक्शंस के अंदर अनलॉक कर रहा हूं। – grimgrom

+0

@grimgrom, हाँ यह है। 'Lock_guard' का उल्लेख किया गया है क्योंकि यह अपवाद सुरक्षा को हासिल करने के लिए बहुत आसान बनाता है लेकिन डेडलॉक्स से बचने की आवश्यकता नहीं है। डेडलॉक्स से बचने के लिए सुनिश्चित करें कि लॉक हमेशा एक ही क्रम में अधिग्रहण किए जाते हैं और _always_ जारी किए जाते हैं, भले ही लॉक अधिग्रहण के बाद कोड कैसे निकलता है। – hmjd

+0

@grimgrom, ध्यान दें कि आप आसानी से अपने 'म्यूटेक्स' वर्ग के लिए अपनी 'लॉक_गार्ड' कक्षा लिख ​​सकते हैं। कन्स्ट्रक्टर में बस 'लॉक() 'और विनाशक में' अनलॉक()'। बस सुनिश्चित करें कि 'Lock_guard'' Mutex' उदाहरण का संदर्भ संग्रहीत करता है और इसकी प्रतिलिपि नहीं करता है। – hmjd

26

std::lock इस उद्देश्य के लिए मौजूद प्रतीत होता है।

दी गई लॉक करने योग्य ऑब्जेक्ट लॉक 1, लॉक 2, ..., लॉकॉक डेडलॉक से बचने के लिए डेडलॉक टालने के लिए एल्गोरिदम का उपयोग करता है। ऑब्जेक्ट लॉक, try_lock, अनलॉक करने के लिए कॉल की एक अनिर्दिष्ट श्रृंखला द्वारा लॉक हैं। यदि किसी अपवाद में परिणामों को लॉक या अनलॉक करने के लिए कॉल, रीक्रोइंग से पहले किसी भी लॉक ऑब्जेक्ट्स के लिए अनलॉक कहा जाता है।

http://en.cppreference.com/w/cpp/thread/lock

2

सी ++ 17 भी है कि एक आरए II शैली में गतिरोध से बचाता है कई mutexes ताला लगा के विशेष उद्देश्य से, lock_guard के लिए इसी तरह के लिए scoped_lock प्रदान करता है।

#include<mutex> 

std::mutex mtx1, mtx2; 
void foo() 
{ 
    std::scoped_lock lck{mtx1, mtx2}; 
    // proceed 
}