2009-03-09 14 views
9

मैं में Boost thread documentation आज इस दिलचस्प पैरा में आए:नकली अनब्लॉक करने

void wait(boost::unique_lock<boost::mutex>& lock) 

...

प्रभाव: atomically कॉल lock.unlock() और ब्लॉक वर्तमान धागा । धागा द्वारा अधिसूचित किए जाने पर अनब्लॉक करेगा-> notify_one() या यह-> notify_all(), या नकली पर कॉल करें। जब थ्रेड अनब्लॉक किया गया था ( किसी भी कारण से), लॉक लॉक.लॉक() पर रिटर्न का इंतजार करने के लिए कॉल करने से पहले पुनः प्राप्त किया गया है। लॉक को लॉक.लॉक() को लॉक करके पुनः प्राप्त किया जाता है यदि फ़ंक्शन अपवाद के साथ निकलता है।

तो मुझे जो दिलचस्पी है वह शब्द "नकली" शब्द का अर्थ है। नकली कारणों के लिए थ्रेड को अनब्लॉक क्यों किया जाएगा? इसे हल करने के लिए क्या किया जा सकता है?

उत्तर

10

This article by Anthony Williams विशेष रूप से विस्तृत है।

नकली पर सक्रिय भविष्यवाणी नहीं की जा सकती है: वे देखने के उपयोगकर्ता के बिंदु से अनिवार्य रूप से यादृच्छिक कर रहे हैं। हालांकि, वे आमतौर पर तब होते हैं जब थ्रेड लाइब्रेरी विश्वसनीय रूप से यह सुनिश्चित नहीं कर सकता कि प्रतीक्षा धागा अधिसूचना को याद नहीं करेगा। चूंकि एक मिस्ड अधिसूचना कंडीशन वैरिएबल बेकार, प्रस्तुत करती है, थ्रेड लाइब्रेरी को जोखिम लेने के बजाय थ्रेड को प्रतीक्षा करता है।

उन्होंने यह भी बताते हैं कि आप timed_wait भार के कि एक अवधि लेने का उपयोग करना चाहिए नहीं, और आप आमतौर संस्करणों है कि एक विधेय

शुरुआत के बग है कि लेने का उपयोग करना चाहिए, और एक कि आसानी से नियम से आसानी से उबरें: वैरिएबल के साथ प्रतीक्षा करते समय हमेशा लूप में अपनी भविष्यवाणी की जांच करें। Timed_wait() से अधिक कपटपूर्ण बग आता है।

This article by Vladimir Prus भी दिलचस्प है।

लेकिन क्यों हम जबकि पाश की क्या ज़रूरत है, नहीं हम लिख सकते हैं:

if (!something_happened) 
    c.wait(m); 

हम नहीं कर सकते। और हत्यारा कारण यह है कि 'प्रतीक्षा' बिना किसी 'सूचना' कॉल के वापसी कर सकता है। इसे नकली wakeup कहा जाता है और स्पष्ट रूप से POSIX द्वारा अनुमत है। अनिवार्य रूप से, 'प्रतीक्षा' से वापस केवल इंगित करता है कि साझा डेटा बदल गया है, ताकि डेटा फिर से मूल्यांकन किया जाना चाहिए।

ठीक है, तो यह अभी तक क्यों तय नहीं है? पहला कारण यह है कि इसे ठीक करने के लिए कोई भी नहीं चाहता है। में 'प्रतीक्षा' करने के लिए कॉल को लपेटना कई अन्य कारणों के लिए एक लूप बहुत वांछित है। लेकिन उन कारणों से स्पष्टीकरण की आवश्यकता है, जबकि नकली वेकअप एक हथौड़ा है जिसे के बिना किसी भी प्रथम वर्ष के छात्र को लागू किया जा सकता है।

+0

ऐसा लगता है कि हम एक ही पृष्ठ ढूंढ रहे हैं, जो पूरी तरह से अप्रत्याशित नहीं है :) –

+1

हाँ, यह आज मेरे शोध का एक सारांश है जब मैंने भयानक बग का कारण बताया कि मैं से पीड़ित था। बूस्ट प्रलेखन इस बिंदु पर स्पष्ट हो सकता है –

+1

मुझे इंतजार और अधिसूचना के लिए पूरे सिस्टम को बढ़ावा मिला है - खासकर बूस्ट :: इंटरप्रोसेस-बहुत निराशाजनक है। अगर आप इसे क्रॉस-प्लेटफॉर्म होने और अब करने की आवश्यकता है तो मैं केवल इसका उपयोग करूंगा। –

2

This blog postfutex सिस्टम कॉल के संदर्भ में लिनक्स का कारण देता है जब किसी प्रक्रिया को सिग्नल वितरित किया जाता है। दुर्भाग्यवश यह किसी और चीज की व्याख्या नहीं करता है (और वास्तव में अधिक जानकारी मांग रहा है)।

Wikipedia entry on spurious wakeups (जो पॉज़िक्स-व्यापी अवधारणा प्रतीत होता है, बीटीडब्ल्यू, बूस्ट तक ही सीमित नहीं है) आपको भी रूचि दे सकता है।

+0

हम्म हाँ यह वास्तव में एक संतोषजनक उत्तर नहीं है कि यह वास्तव में केवल एक मंच पर लागू होता है, हालांकि मुझे लगता है कि यह वास्तव में लिनक्स पर "सही ढंग से" काम करने के लिए अविश्वसनीय रूप से कठिन है, तो यह हो सकता है नकली wakeups को दस्तावेज करने का वैध कारण –