एक ताला पर दौड़ की स्थिति को क्या रोकता है?


24

मुझे पता है कि डेटा दौड़ क्या है, और कैसे ताले / म्यूटेक्स / सेमाफोर उन्हें रोकने में मदद करते हैं, की मूल बातें समझते हैं। लेकिन क्या होता है अगर आपके पास लॉक पर "रेस कंडीशन" है? उदाहरण के लिए, दो अलग-अलग धागे, शायद एक ही अनुप्रयोग में, लेकिन विभिन्न प्रोसेसर पर चल रहे हैं, एक ही समय में लॉक प्राप्त करने का प्रयास करें ।

फिर क्या होता है? उसे रोकने के लिए क्या किया जाता है? क्या यह असंभव है, या सिर्फ सादा संभावना नहीं है? या यह एक वास्तविक दौड़ हालत होने की प्रतीक्षा कर रहा है?



और पीएसई पर एक संबंधित प्रश्न यहां: प्रोग्रामर.स्टैकएक्सचेंज
शाफ़्ट सनकी

आप लॉक का अधिग्रहण करने के लिए एक लॉक प्राप्त करते हैं;) (दूसरे शब्दों में, यदि आपके लॉक की एक दौड़ की स्थिति है, तो इसे सही तरीके से लागू नहीं किया जाता है - एक लॉक एक निर्माण को बहुत अधिक परिभाषित करता है जो आपसी बहिष्कार को लागू करता है)
Tangrs

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

जवाबों:


36

क्या यह असंभव है, या सिर्फ सादा संभावना नहीं है?

असंभव। यह अलग-अलग तरीकों से लागू किया जा सकता है, उदाहरण के लिए, तुलना-और-स्वैप के माध्यम से जहां हार्डवेयर अनुक्रमिक निष्पादन की गारंटी देता है। यह कई कोर या कई सॉकेट की उपस्थिति में थोड़ा जटिल हो सकता है और कोर के बीच एक जटिल प्रोटोकॉल की आवश्यकता होती है , लेकिन यह सब ध्यान रखा जाता है।


3
धन्यवाद ... भगवान ... यह हार्डवेयर में संभाला जाता है ... (या कम से कम एक स्तर जो हम छूते हैं।)
corsiKa

2
@ मैं इस पर विश्वास नहीं कर सकता ... इस जवाब ने मुझे 5 मिनट से भी कम समय दिया और यह मेरे चार सैकड़ों उत्तर (मुख्य रूप से एसओ) में से तीसरा सबसे अधिक मतदान है। और शायद सबसे छोटा भी।
माॅर्टिनस

1
@maaartinus - छोटा और मीठा कभी-कभी करता है।
बोबसन

17

परमाणु "टेस्ट और सेट" ऑपरेशन की अवधारणा का अध्ययन करें।

अनिवार्य रूप से ऑपरेशन को विभाजित नहीं किया जा सकता है - यह दो चीजों के लिए एक ही समय में करना संभव नहीं है। यह एक मान की जाँच करेगा, अगर यह स्पष्ट है, तो इसे सेट करें, और जब यह परीक्षण था तब मान लौटाएं। एक लॉक ऑपरेशन में, परिणाम हमेशा एक परीक्षण और सेट के बाद "लॉक == ट्रू" होगा, एकमात्र अंतर यह सेट किया गया था या शुरू में नहीं।

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


2
असल में, यदि हार्डवेयर किसी स्तर पर आंतरिक रूप से अनुक्रमिक नहीं है, तो इसमें एक तंत्र होगा जो इसे उन संबंधों को तोड़ने की अनुमति देता है जो अन्यथा हो सकते हैं।
बिल माइकेल

@BillMichell, मुझे ऐसा सोचना चाहिए था। असल में, मैंने किया; मुझे नहीं पता था कि मेरी धारणा सही है या नहीं।
गैविन हॉवर्ड

2

सीधे शब्दों में कहें कि कोड को महत्वपूर्ण खंड में लाने के लिए विशेष रूप से डिज़ाइन किया गया है ताकि एक दौड़ की स्थिति आपसी बहिष्कार का उल्लंघन नहीं करेगी।

अधिकांश समय परमाणु तुलना और सेट लूप का उपयोग किया जाता है जो हार्डवेयर स्तर पर निष्पादित होते हैं

while(!CompareAndSet(&lock, false, true));//busy loop won't continue until THIS thread has set the lock to true
//critical section
CompareAndSet(&lock, true, false);

इसके अभाव में आपसी बहिष्कार को सक्षम करने के लिए अच्छी तरह से अध्ययन किए गए सॉफ़्टवेयर समाधान हैं


1

यह संभव नहीं है कि दो (या अधिक) धागे एक ही समय में लॉक का अधिग्रहण करें। उदाहरण के लिए सिंक्रनाइज़ेशन विधियों के कुछ प्रकार हैं:

सक्रिय प्रतीक्षा - स्पिन लॉक

स्यूडोकोड:

1. while ( xchg(lock, 1) == 1); - entry protocole

XCHG परमाणु ऑपरेशन (x86 आर्किटेक्चर पर मौजूद) का एक उदाहरण है, जो पहले "लॉक" वेरिएबल के लिए नया मान सेट करता है और उसके बाद दूसरा वैल्यू देता है। परमाणु का मतलब यह है कि यह नए मूल्य निर्धारित करने और पुराने वापस लौटने के बीच के उदाहरण में बाधित नहीं हो सकता है। परमाणु - नियतात्मक परिणाम चाहे जो भी हो।

2. Your code
3. lock = 0; - exit protocol

जब ताला 0 के बराबर होता है तो एक और धागा महत्वपूर्ण खंड में प्रवेश कर सकता है - जबकि लूप समाप्त होता है।

थ्रेड सस्पेंडिंग - उदाहरण के लिए सेमाफोर की गिनती

दो परमाणु आपरेशन भी बना हुआ है .Wait()और .Signal()और पूर्णांक चर इसे कहते देता है हमारे पास int currentValue

Wait():
if (currentValue > 0) currentValue -= 1;
else suspend current thread;

Signal():
If there exists thread suspended by semaphore wake up one of them
Else currentValue += 1;

अब महत्वपूर्ण खंड समस्या को हल करना वास्तव में आसान है:

स्यूडोकोड:

mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();

आमतौर पर आपके प्रोग्रामिंग थ्रेड एपीआई आपको सेमीफोर महत्वपूर्ण अनुभाग में अधिकतम समवर्ती धागे को निर्दिष्ट करने की क्षमता प्रदान करना चाहिए। स्पष्ट रूप से मल्टीथ्रेडेड सिस्टम (म्यूटेक्स, मॉनिटर, बाइनरी सेमाफोर आदि) में अधिक प्रकार के सिंक्रनाइज़ेशन हैं, लेकिन वे उपरोक्त विचारों पर आधारित हैं। कोई यह तर्क दे सकता है कि थ्रेड सस्पेंड करने वाले तरीकों को सक्रिय प्रतीक्षा के लिए प्राथमिकता दी जानी चाहिए (इसलिए सीपीयू व्यर्थ नहीं है) - यह हमेशा सच नहीं है। जब थ्रेड निलंबित किया जा रहा है - संदर्भ स्विच नामक महंगा ऑपरेशन इसे जगह लेता है। हालाँकि यह उचित है जब प्रतीक्षा समय कम हो (धागे की संख्या ~ कोर की संख्या)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.