लिनक्स कर्नेल में, स्पिनलॉक पकड़े हुए आप क्यों सो नहीं सकते?स्पिनलॉक पकड़े हुए आप सो क्यों नहीं सकते?
उत्तर
उदाहरण: आपका चालक निष्पादित कर रहा है और उसने अभी एक लॉक निकाला है जो इसके डिवाइस तक पहुंच नियंत्रित करता है। लॉक होने पर, डिवाइस एक बाधा उत्पन्न करता है, जिससे आपके इंटरप्ट हैंडलर को चलाने का कारण बनता है। डिवाइस तक पहुंचने से पहले इंटरप्ट हैंडलर को लॉक भी प्राप्त करना होगा। एक इंटरप्ट हैंडलर में एक स्पिनलॉक लेना एक वैध बात है; यही कारण है कि स्पिनलॉक ऑपरेशन सोते नहीं हैं। लेकिन क्या होता है यदि अंतराल दिनचर्या उसी प्रोसेसर में मूल रूप से लॉक निकालने वाले कोड के रूप में निष्पादित होती है? जबकि इंटरप्ट हैंडलर कताई कर रहा है, तो अनइंटरप्ट कोड लॉक को रिलीज़ करने में सक्षम नहीं होगा। वह प्रोसेसर हमेशा के लिए स्पिन जाएगा।
जाहिर है, स्पिनलॉक्स का उपयोग करके संरक्षित महत्वपूर्ण वर्गों में इंटरप्ट को अक्षम करके इस स्थिति से बचा जा सकता है। उदाहरण के लिए, ओबेरॉन इस दृष्टिकोण को लेता है (पृष्ठ 57)। http://e-collection.library.ethz.ch/eserv/eth2260/eth-26082-02.pdf – gjain
ऐसा ही एक और व्याख्या यह है कि, एक spinlock संदर्भ में शुफ़ा अक्षम किया गया है है।
यह अक्षम क्यों है? – Bandicoot
क्या विलुप्त होने के अलावा, मान लें कि एक प्रक्रिया एक स्पिलॉक पकड़े हुए सोती है। यदि निर्धारित की गई नई प्रक्रिया एक ही स्पिनलॉक प्राप्त करने का प्रयास करती है, तो यह लॉक के लिए कताई शुरू हो जाती है। चूंकि नई प्रक्रिया कताई रखती है, इसलिए पहली प्रक्रिया को शेड्यूल करना संभव नहीं है और इस प्रकार लॉक को दूसरी प्रक्रिया को हमेशा के लिए स्पिन करने के लिए कभी जारी नहीं किया जाता है और हमारे पास डेडलॉक होता है।
ऐसा नहीं है कि स्पिन लॉक रखने के दौरान सो नहीं सकता है। यह बहुत ही खराब ऐसा करने का विचार है। का हवाला देते हुए LDD:
इसलिए, spinlocks पर लागू होने वाला कोर नियम यह है कि किसी भी कोड चाहिए, एक spinlock दबाते हुए, परमाणु होना है। यह सो नहीं सकता वास्तव में, यह किसी भी कारण से प्रोसेसर को सेवा इंटरप्ट्स (और कभी-कभी तब भी नहीं) को छोड़कर छोड़ नहीं सकता है।
ऊपर वर्णित किसी भी डेडलॉक के परिणामस्वरूप एक अप्राप्य स्थिति हो सकती है। एक और चीज जो हो सकती है वह यह है कि स्पिनलॉक एक सीपीयू पर बंद हो जाता है, और फिर जब धागा सो जाता है, तो यह दूसरे सीपीयू पर उठता है, जिसके परिणामस्वरूप कर्नेल घबरा जाता है।
शीर्ष खिलाड़ी की इस टिप्पणी का उत्तर देना, एक स्पिन ताला संदर्भ में, शुफ़ा विकलांग केवल एक uniprocessor पूर्व emptible गिरी के मामले में है, क्योंकि अक्षम करने शुफ़ा प्रभावी रूप से दौड़ से बचाता है।
गिरी CONFIG_SMP बिना संकलित किया गया है, लेकिन CONFIG_PREEMPT सेट कर दिया जाता है, तो बस पूर्वक्रय, जो किसी भी दौड़ को रोकने के लिए पर्याप्त है को निष्क्रिय spinlocks। ज्यादातर उद्देश्यों के लिए, हम एसएमपी के समकक्ष प्रीपेप्शन के बारे में सोच सकते हैं, और इसके बारे में चिंता न करें।
http://www.kernel.org/pub/linux/kernel/people/rusty/kernel-locking/index.html
मैं विलियम की प्रतिक्रिया (अपने उदाहरण) से असहमत हैं। वह दो अलग-अलग अवधारणाओं को मिला रहा है: मोचन और सिंक्रनाइज़ेशन।
व्यवधान प्रसंग एक प्रक्रिया प्रसंग जगह ले लेना सकता है और इस तरह वहाँ एक संसाधन दोनों द्वारा साझा, हम
spin_lock_irqsave()
को
उपयोग करने के लिए (1) को निष्क्रिय आईआरक्यू की जरूरत है (2) ताला हासिल। चरण 1 तक, हम अंतःस्थापित छूट को अक्षम कर सकते हैं।
मुझे लगता है कि this धागा बहुत विश्वसनीय है। नींद() का मतलब है कि एक धागा/प्रक्रिया सीपीयू और कन्थ स्विच को दूसरे पर स्पिनलॉक जारी किए बिना उत्पन्न करती है, यही कारण है कि यह गलत है।
सहमत हैं, अगर मैं गलत नहीं हूं विलियम की समस्या को बाधा रोकथाम को अक्षम करने के लिए उपयुक्त spin_lock फ़ंक्शन का उपयोग कर हल किया गया है। नींद की समस्या अलग है, आपको केवल स्पिनलॉक महत्वपूर्ण खंड में सोने से बचना चाहिए, अन्यथा आपको खराब प्रदर्शन या डेडलॉक मिलेगा। –
मुख्य बिंदु लिनक्स कर्नेल में है, स्पिन लॉक प्राप्त करने से प्रीमिशन अक्षम हो जाएगा। इस प्रकार एक स्पिन लॉक पकड़े हुए सोते हुए संभावित रूप से डेडलॉक हो सकता है।
उदाहरण के लिए, थ्रेड ए स्पिन लॉक प्राप्त करता है। थ्रेड ए को तब तक छूट नहीं दी जाएगी जब तक कि यह लॉक जारी न करे। जब तक थ्रेड ए जल्दी से अपना काम करता है और लॉक जारी करता है, तब तक कोई समस्या नहीं होती है। लेकिन यदि ताला ए लॉक रखने के दौरान सोता है, तो थ्रेड बी को चलाने के लिए निर्धारित किया जा सकता है क्योंकि नींद समारोह शेड्यूलर का आह्वान करेगा। और थ्रेड बी एक ही लॉक भी प्राप्त कर सकता है। थ्रेड बी भी छूट को अक्षम करता है और ताला हासिल करने का प्रयास करता है। और एक डेडलॉक होता है। थ्रेड बी को लॉक कभी नहीं मिलेगा क्योंकि थ्रेड ए इसे रखता है, और थ्रेड ए कभी भी नहीं चल पाएगा क्योंकि थ्रेड बी प्रीपेशन को अक्षम करता है।
और क्यों पहली जगह में छूट को अक्षम करना? मुझे लगता है कि ऐसा इसलिए है क्योंकि हम नहीं चाहते हैं कि अन्य प्रोसेसर पर धागे बहुत लंबे समय तक प्रतीक्षा करें।
यदि प्रीम्प्शन अक्षम है, तो मौजूदा प्रक्रिया के दौरान थ्रेड बी को चालू करने के लिए निर्धारित किया जा सकता है? –
"नींद" कार्रवाई शेड्यूलर का आह्वान करेगी हालांकि प्रीम्प्शन अक्षम है। –
कुल नैन वांग के साथ सहमत हैं। मुझे लगता है कि सबसे महत्वपूर्ण अवधारणा "प्रीम्प्शन" & "शेड्यूलिंग" है और स्पिनलॉक कब प्राप्त होता है। जब स्पिनलॉक अधिग्रहण किया जाता है, तो प्रीम्प्शन अक्षम होता है (सत्य या नहीं, मुझे नहीं पता, लेकिन मान लें कि यह सही है), इसका मतलब है कि टाइमर इंटरप्ट वर्तमान स्पिनलॉक धारक को रोक नहीं सकता है, लेकिन वर्तमान स्पिनलॉक होल्ड अभी भी नींद के कर्नेल कार्यों को कॉल करता है & सक्रिय रूप से शेड्यूलर & "अन्य कार्य" चलाएं। यदि पहला स्पिनलॉक धारक के रूप में एक ही स्पिनलॉक प्राप्त करना चाहते हैं, तो "दूसरा कार्य" हुआ है, यहां समस्या आती है: चूंकि प्रीमिशन पहले स्पिनलॉक धारक द्वारा पहले ही अक्षम कर दिया गया है, "दूसरा कार्य" जिसे पहले स्पिनलॉक द्वारा सक्रिय रूप से शेड्यूलर द्वारा कॉल किया जाता है धारक, को पूर्ववत नहीं किया जा सकता है, इसलिए इसकी कताई हमेशा सीपीयू लेती है, यही कारण है कि डेडलॉक होता है।
मुझे लगता है कि इस mail एक स्पष्टता जवाब है:
एक प्रक्रिया रोका नहीं जा सकता है और न ही नींद एक spinlock कारण spinlocks व्यवहार दबाते हुए। अगर एक प्रक्रिया एक स्पिनलॉक पकड़ लेती है और इसे जारी करने से पहले सो जाती है। स्पिनलॉक को पकड़ने के लिए एक दूसरी प्रक्रिया (या एक इंटरप्ट हैंडलर) व्यस्त प्रतीक्षा करेगी। एक यूनिप्रोसेसर मशीन पर दूसरी प्रक्रिया सीपीयू को लॉक कर देगी जिससे पहली प्रक्रिया जागने और स्पिनलॉक को छोड़ने की इजाजत नहीं दी जाएगी, इसलिए दूसरी प्रक्रिया जारी रह सकती है, यह मूल रूप से एक डेडलॉक है।
- 1. आप UnRegisterStartupScript क्यों नहीं कर सकते?
- 2. मेरे सी ++ अपवाद क्यों नहीं पकड़े जा रहे हैं?
- 3. आप '।' को अधिभार क्यों नहीं दे सकते सी ++ में ऑपरेटर?
- 4. आप पाइथन में ऑब्जेक्ट्स में विशेषता क्यों नहीं जोड़ सकते?
- 5. आप फ़ंक्शन अभिव्यक्ति को क्यों स्ट्रिंग नहीं कर सकते?
- 6. आप विस्तार विधियों को सीधे क्यों नहीं बुला सकते हैं?
- 7. आप रिलीज मोड में वेबसाइट क्यों नहीं बना सकते?
- 8. सीएएसई उपकरण सफल क्यों नहीं हुए?
- 9. हास्केल अपवाद केवल आईओ मोनैड के अंदर क्यों पकड़े जा सकते हैं?
- 10. पकड़े 2^63 -1 लंबे
- 11. जेनरेटर क्यों मसालेदार नहीं हो सकते हैं?
- 12. फेंक: सभी goroutines सो रहे - गतिरोध
- 13. एक लंबे एक्सेल प्रदर्शन करते समय आप इनो सेटअप को जमे हुए क्यों नहीं देखते हैं?
- 14. सी में आप क्या नहीं कर सकते हैं जिसे आप उद्देश्य-सी में कर सकते हैं?
- 15. आप प्राथमिक कुंजी के रूप में SQLite ROWID का उपयोग क्यों नहीं कर सकते?
- 16. आप एक इटरेटर संदर्भ में एक असुरक्षित कीवर्ड का उपयोग क्यों नहीं कर सकते?
- 17. आप एक एसटीएल कंटेनर में एक कॉन्स ऑब्जेक्ट क्यों नहीं डाल सकते?
- 18. Qt4: QTableView माउस बटन ईवेंट पकड़े नहीं गए
- 19. आप खिड़की की एक ओवरराइड संपत्ति क्यों हटा सकते हैं?
- 20. लिनक्स कर्नेल: स्पिनलॉक एसएमपी: spin_lock_irq एसएमपी संस्करण में preempt_disable() क्यों है?
- 21. प्रतिबिंब अपवाद पकड़े जाने में असमर्थ?
- 22. Jquery: कैसे सो या देरी?
- 23. कैसे जांचें कि कोई थ्रेड सो रहा है या नहीं?
- 24. विधि में लैम्ब्डा अभिव्यक्ति होने पर आप डीबगिंग को संपादित और जारी क्यों नहीं कर सकते?
- 25. WinForms में, आप अन्य धागे से यूआई नियंत्रण क्यों अपडेट नहीं कर सकते?
- 26. आप सामान्य (अनिश्चित) कोड में क्यों विभाजित नहीं हो सकते हैं?
- 27. आप PHP में अमूर्त कक्षाओं से अमूर्त कार्यों को क्यों नहीं बुला सकते?
- 28. सदस्य प्रारंभकर्ताओं में आप 'इस' का उपयोग क्यों नहीं कर सकते?
- 29. LINQ से SQL - आप ORDER BY के बाद WHERE का उपयोग क्यों नहीं कर सकते?
- 30. घुंघराले ब्रेसिज़ के बिना आप लूप में इंटीजर को इंटिग क्यों नहीं दे सकते?
oversimplified: क्योंकि आप spinlock साथ अन्य सभी को जाने से रोक दिया है, ताकि वे शेड्यूल नहीं कर सकते लेकिन अपने होल्डिंग धागा करने के लिए कुछ भी। – user562374