इसलिए कोई तकनीकी कारण क्या है?
मैंने cmeerw के उत्तर को ऊपर उठाया क्योंकि मुझे विश्वास है कि उसने तकनीकी कारण दिया है। चलो इसके माध्यम से चलते हैं। आइए दिखाएं कि समिति ने condition_variable
mutex
पर प्रतीक्षा करने का निर्णय लिया था। यहाँ है कि डिजाइन का उपयोग कर कोड है:
void foo()
{
mut.lock();
// mut locked by this thread here
while (not_ready)
cv.wait(mut);
// mut locked by this thread here
mut.unlock();
}
यह ठीक है कि कैसे एक एक condition_variable
उपयोग नहीं करना चाहिए। क्षेत्रों के साथ चिह्नित क्षेत्रों में:
// mut locked by this thread here
एक अपवाद सुरक्षा समस्या है, और यह एक गंभीर है। यदि इन क्षेत्रों में एक अपवाद फेंक दिया गया है (या cv.wait
स्वयं), तो म्यूटेक्स की लॉक स्थिति तब तक लीक हो जाती है जब तक कि अपवाद को पकड़ने और इसे अनलॉक करने के लिए कहीं भी प्रयास/पकड़ न रखा जाए। लेकिन यह सिर्फ इतना कोड है कि आप प्रोग्रामर को लिखने के लिए कह रहे हैं।
मान लें कि प्रोग्रामर जानता है कि अपवाद सुरक्षित कोड कैसे लिखना है, और इसे प्राप्त करने के लिए unique_lock
का उपयोग करना जानता है। अब कोड इस तरह दिखता है:
void foo()
{
unique_lock<mutex> lk(mut);
// mut locked by this thread here
while (not_ready)
cv.wait(*lk.mutex());
// mut locked by this thread here
}
यह बहुत बेहतर है, लेकिन यह अभी भी एक अच्छी स्थिति नहीं है। condition_variable
इंटरफ़ेस प्रोग्रामर को काम करने के लिए अपने रास्ते से बाहर निकल रहा है। lk
गलती से एक mutex का संदर्भ नहीं देता है तो एक संभावित शून्य सूचक dereference है। और यह देखने के लिए condition_variable::wait
के लिए कोई रास्ता नहीं है कि यह थ्रेड mut
पर लॉक का मालिक है।
ओह, बस याद किया गया है कि प्रोग्रामर गलत है unique_lock
सदस्य फ़ंक्शन mutex का पर्दाफाश करने के लिए चुन सकता है। यहां विनाशकारी होगा।
अब कैसे कोड वास्तविक condition_variable
एपीआई कि एक unique_lock<mutex>
लेता है के साथ लिखा है पर ध्यान दें:
void foo()
{
unique_lock<mutex> lk(mut);
// mut locked by this thread here
while (not_ready)
cv.wait(lk);
// mut locked by this thread here
}
- इस कोड के रूप में सरल रूप में यह मिल सकता है।
- यह अपवाद सुरक्षित है।
wait
फ़ंक्शन lk.owns_lock()
देख सकता है और false
पर अपवाद फेंक सकता है।
ये तकनीकी कारण हैं जो condition_variable
के एपीआई डिज़ाइन को चलाते हैं।
साथ ही, condition_variable::wait
नहीं ले एक क्योंकि lock_guard<mutex>
lock_guard<mutex>
आप कैसे कहते हैं है है: मैं lock_guard<mutex>
नष्ट हो जब तक इस म्युटेक्स पर ताला के मालिक हैं। लेकिन जब आप condition_variable::wait
पर कॉल करते हैं, तो आप पूरी तरह से म्यूटेक्स पर लॉक जारी करते हैं। ताकि कार्रवाई lock_guard
उपयोग केस/कथन के साथ असंगत है।
हम इतना है कि एक, कार्यों से ताले लौट सकते हैं उन्हें कंटेनर में डाल दिया, और लॉक/एक अपवाद सुरक्षित तरीके से गैर-दायरे वाले पैटर्न में mutexes अनलॉक, तो unique_lock
condition_variable::wait
के लिए स्वाभाविक पसंद था वैसे भी unique_lock
की जरूरत है।
अद्यतन
bamboon है कि मैं इसके विपरीत condition_variable_any
नीचे टिप्पणी में सुझाव दिया है, इसलिए यहाँ जाता है:
प्रश्न: क्यों टेम्प्लेट नहीं condition_variable::wait
जाता है जिससे कि मैं इसे करने के लिए कोई Lockable
प्रकार पारित कर सकते हैं ?
उत्तर:
यह वास्तव में करने के लिए शांत कार्यक्षमता है। उदाहरण के लिए this paper कोड को प्रदर्शित करता है जो shared_lock
(rwlock) पर एक साझा चर पर साझा मोड में प्रतीक्षा करता है (पॉज़िक्स दुनिया में कुछ अनदेखा है, लेकिन फिर भी बहुत उपयोगी है)। हालांकि कार्यक्षमता अधिक महंगा है।
तो समिति इस कार्यक्षमता के साथ एक नए प्रकार की शुरुआत की:
`condition_variable_any`
इस condition_variable
एडाप्टर एक साथ किसी भी ताला-युक्त प्रकार पर इंतजार कर सकते हैं। यदि इसमें lock()
और unlock()
सदस्य हैं, तो आप जाने के लिए अच्छे हैं। condition_variable_any
का एक उचित कार्यान्वयन condition_variable
डेटा सदस्य और shared_ptr<mutex>
डेटा सदस्य की आवश्यकता है।
क्योंकि यह नई कार्यक्षमता आपके मूल condition_variable::wait
से अधिक महंगी है, और क्योंकि condition_variable
इतना निम्न स्तर का टूल है, यह बहुत उपयोगी लेकिन अधिक महंगी कार्यक्षमता एक अलग वर्ग में डाल दी गई थी ताकि आप इसका उपयोग केवल इसके लिए ही कर सकें ।
क्या आप इस बारे में उलझन में हैं कि आपको एक कंडीशन वैरिएबल के साथ लॉक/म्यूटेक्स की आवश्यकता क्यों है, या लॉक और म्यूटेक्स के बीच के अंतर के बारे में या क्यों एक कंडीशन वेरिएबल एक अद्वितीय लॉक का उपयोग करता है और म्यूटेक्स नहीं? – Brady
"क्यों एक कंडीशन वैरिएबल एक अद्वितीय लॉक का उपयोग करता है और म्यूटेक्स नहीं"। –