मैं std::condition_variable(lock,pred)
के कुलपति ++ कार्यान्वयन देखा है, मूल रूप से, यह इस तरह दिखता है:std :: condition_variable में संभावित दौड़ की स्थिति?
template<class _Predicate>
void wait(unique_lock<mutex>& _Lck, _Predicate _Pred)
{ // wait for signal and test predicate
while (!_Pred())
wait(_Lck);
}
असल में, नग्न wait
कॉल _Cnd_waitX
जो _Cnd_wait
जो do_wait
जो cond->_get_cv()->wait(cs);
(कॉल कॉल कॉल इन सब में हैं फ़ाइल cond.c)।
cond->_get_cv()
Concurrency::details::stl_condition_variable_interface
देता है।
यदि हम फ़ाइल primitives.h
पर जाते हैं, हम देखते हैं कि विंडोज 7 और इसके बाद के संस्करण के अंतर्गत, हम वर्ग stl_condition_variable_win7
जो पुराने अच्छा Win32 CONDITION_VARIABLE
, और wait
कॉल __crtSleepConditionVariableSRW
शामिल है।
कुछ असेंबली डीबग करना, __crtSleepConditionVariableSRW
बस SleepConditionVariableSRW
फ़ंक्शन पॉइंटर निकालें, और इसे कॉल करें।
यहां तक कि बात है: जहां तक मुझे पता है, Win32 CONDITION_VARIABLE
कर्नेल ऑब्जेक्ट नहीं है, लेकिन उपयोगकर्ता मोड एक है। इसलिए, यदि कुछ धागे इस चर को सूचित करते हैं और कोई धागा वास्तव में उस पर सो नहीं जाता है, तो आप अधिसूचना खो देते हैं, और थ्रेड समय तक पहुंचने तक थ्रेड रहेगा या कुछ अन्य धागे इसे सूचित करते हैं। एक छोटा कार्यक्रम वास्तव में इसे साबित कर सकता है - यदि आप अधिसूचना के बिंदु को याद करते हैं - आपका धागा सो रहेगा हालांकि कुछ अन्य धागे ने इसे अधिसूचित किया है।
मेरा प्रश्न इस तरह है:
एक थ्रेड एक शर्त चर पर इंतजार करता है और भविष्यवाणी झूठी रिटर्न देता है। फिर, ऊपर वर्णित कॉल की पूरी श्रृंखला जगह लेता है। उस समय, एक और थ्रेड ने पर्यावरण को बदल दिया ताकि भविष्यवाणी सही हो जाएगी और हालत चर को सूचित करता है। हमने मूल धागे में भविष्यवाणी की, लेकिन हम अभी भी SleepConditionVariableSRW
में नहीं गए - कॉल श्रृंखला बहुत लंबी है।
इसलिए, भले ही हम हालत चर और विधेय हालत चर पर डाल निश्चित रूप से सच है (क्योंकि सूचक इसलिए बनाया), हम अभी भी हालत चर पर, अवरुद्ध कर रहे हैं संभवतः हमेशा के लिए वापस आ जाएगी अधिसूचित।
क्या यह व्यवहार करना चाहिए? ऐसा लगता है कि एक बड़ी बदसूरत दौड़ की स्थिति होने की प्रतीक्षा है। यदि आप एक शर्त चर को सूचित करते हैं और यह अनुमानित सत्य सत्य देता है - थ्रेड को अनब्लॉक करना चाहिए। लेकिन अगर हम भविष्यवाणी की जांच करने और सोने के लिए लिम्बो में हैं - हम हमेशा के लिए अवरुद्ध हैं। std::condition_variable::wait
एक परमाणु कार्य नहीं है।
मानक इसके बारे में क्या कहता है और क्या यह वास्तव में दौड़ की स्थिति है?
आह, मुझे याद आया "यहां तक कि अगर साझा चर परमाणु है ..." जो मुझे दिमाग में था। –
@ डेविडहाइम: ध्यान दें कि यह cppreference द्वारा दिया गया एक संकेत है। मानक इस तरह के कुछ भी नहीं कहता है। 'std :: condition_variable' (साथ ही सामान्य रूप से हालत चर) प्रतीक्षा और अधिसूचनाओं के बीच एक रिश्ता बनाता है और एक म्यूटेक्स धारण करता है। यह माना जाता है कि इस तरह से एक mutex प्राप्त करने के लिए आपके पास वैध कारण है। या नहीं। उस म्यूटेक्स के साथ क्या करना है आपका व्यवसाय है। एकमात्र चीज हालत चर वास्तव में एक म्यूटेक्स जारी करता है और एक प्रतीक्षा स्थिति * परमाणु * दर्ज करें। "हालत" भाग पूरी तरह से आपके ऊपर है। – conio