जब मल्टीथ्रेडेड एप्लिकेशन लिखते हैं, तो अनुभवी सबसे आम समस्याओं में से एक दौड़ की स्थिति है।
समुदाय के लिए मेरे प्रश्न हैं:
दौड़ की स्थिति क्या है?
आप उनका पता कैसे लगाते हैं?
आप उन्हें कैसे संभालेंगे?
अंत में, आप उन्हें होने से कैसे रोकेंगे?
जब मल्टीथ्रेडेड एप्लिकेशन लिखते हैं, तो अनुभवी सबसे आम समस्याओं में से एक दौड़ की स्थिति है।
समुदाय के लिए मेरे प्रश्न हैं:
दौड़ की स्थिति क्या है?
आप उनका पता कैसे लगाते हैं?
आप उन्हें कैसे संभालेंगे?
अंत में, आप उन्हें होने से कैसे रोकेंगे?
जवाबों:
एक दौड़ की स्थिति तब होती है जब दो या अधिक थ्रेड साझा डेटा तक पहुंच सकते हैं और वे एक ही समय में इसे बदलने की कोशिश करते हैं। चूँकि थ्रेड शेड्यूलिंग एल्गोरिदम किसी भी समय थ्रेड्स के बीच स्वैप कर सकता है, आप उस क्रम को नहीं जानते हैं जिसमें थ्रेड्स साझा किए गए डेटा तक पहुँचने का प्रयास करेंगे। इसलिए, डेटा में परिवर्तन का परिणाम थ्रेड शेड्यूलिंग एल्गोरिदम पर निर्भर है, अर्थात डेटा को एक्सेस / बदलने के लिए दोनों थ्रेड "रेसिंग" हैं।
समस्याएँ अक्सर तब होती हैं जब एक थ्रेड "चेक-एक्ट-एक्ट" करता है (उदाहरण के लिए "चेक" यदि मान X है, तो "एक्ट" कुछ ऐसा करने के लिए जो मूल्य X पर निर्भर करता है) और दूसरा थ्रेड वैल्यू में कुछ करता है "चेक" और "अधिनियम" के बीच। उदाहरण के लिए:
if (x == 5) // The "Check"
{
y = x * 2; // The "Act"
// If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
// y will not be equal to 10.
}
बिंदु जा रहा है, y 10 हो सकता है, या यह कुछ भी हो सकता है, इस पर निर्भर करता है कि चेक और अधिनियम के बीच एक और धागा एक्स बदल गया या नहीं। आपके पास जानने का कोई वास्तविक तरीका नहीं है।
दौड़ की स्थितियों को होने से रोकने के लिए, आप आमतौर पर साझा किए गए डेटा के चारों ओर एक लॉक लगाते हैं ताकि यह सुनिश्चित किया जा सके कि एक समय में केवल एक धागा डेटा तक पहुंच सकता है। इसका मतलब कुछ इस तरह होगा:
// Obtain lock for x
if (x == 5)
{
y = x * 2; // Now, nothing can change x until the lock is released.
// Therefore y = 10
}
// release lock for x
एक "दौड़ की स्थिति" तब मौजूद होती है जब एक साझा संसाधन तक पहुंचने वाले मल्टीथ्रेडेड (या अन्यथा समानांतर) कोड इस तरह से ऐसा कर सकता है जिससे अप्रत्याशित परिणाम हो सकते हैं।
इस उदाहरण को लें:
for ( int i = 0; i < 10000000; i++ )
{
x = x + 1;
}
यदि आपके पास 5 धागे हैं जो एक साथ इस कोड को निष्पादित करते हैं, तो x WULULD का मूल्य 50,000,000 तक नहीं है। यह वास्तव में प्रत्येक रन के साथ अलग-अलग होगा।
ऐसा इसलिए है क्योंकि प्रत्येक थ्रेड के लिए x का मान बढ़ाने के लिए, उन्हें निम्नलिखित कार्य करने होंगे: (सरलीकृत, स्पष्ट रूप से)
X का मान पुनः प्राप्त करें इस मान में 1 जोड़ें इस मान को x में संग्रहीत करें
कोई भी धागा किसी भी समय इस प्रक्रिया में किसी भी चरण में हो सकता है, और साझा संसाधन शामिल होने पर वे एक दूसरे पर कदम रख सकते हैं। X की स्थिति को दूसरे थ्रेड द्वारा उस समय के दौरान बदला जा सकता है जब x पढ़ा जा रहा हो और जब वह वापस लिखा जाए।
मान लें कि एक थ्रेड x का मान प्राप्त करता है, लेकिन इसे अभी तक संग्रहीत नहीं किया है। एक और धागा भी x का समान मान निकाल सकता है (क्योंकि किसी भी धागे ने इसे अभी तक नहीं बदला है) और फिर वे दोनों एक ही मूल्य (x + 1) को वापस x में संग्रहीत कर रहे होंगे !
उदाहरण:
थ्रेड 1: x को पढ़ता है, मान 7 है थ्रेड 1: 1 से x जोड़ें, मान अब 8 है थ्रेड 2: x को पढ़ता है, मान 7 है थ्रेड 1: स्टोर एक्स में 8 थ्रेड 2: 1 से x जोड़ता है, मान अब 8 है धागा 2: स्टोर एक्स में 8
साझा संसाधन तक पहुँचने वाले कोड से पहले कुछ प्रकार के लॉकिंग तंत्र को नियोजित करके दौड़ की स्थितियों से बचा जा सकता है :
for ( int i = 0; i < 10000000; i++ )
{
//lock x
x = x + 1;
//unlock x
}
यहां, हर बार 50,000,000 के रूप में उत्तर निकलता है।
लॉकिंग के बारे में अधिक जानने के लिए: म्यूटेक्स, सेमाफोर, महत्वपूर्ण अनुभाग, साझा संसाधन।
रेस कंडीशन क्या है?
आप शाम 5 बजे किसी फिल्म में जाने की योजना बना रहे हैं। आप शाम 4 बजे टिकटों की उपलब्धता के बारे में पूछताछ करते हैं। प्रतिनिधि का कहना है कि वे उपलब्ध हैं। आप आराम करें और शो से 5 मिनट पहले टिकट खिड़की पर पहुँचें। मुझे यकीन है कि आप अनुमान लगा सकते हैं कि क्या होता है: यह एक पूर्ण घर है। यहाँ समस्या जाँच और कार्रवाई के बीच की अवधि में थी। आपने 4 से पूछताछ की और 5. पर काम किया। इस बीच, किसी और ने टिकट हड़प लिया। यह एक दौड़ की स्थिति है - विशेष रूप से दौड़ स्थितियों का एक "चेक-एक्ट-एक्ट" परिदृश्य।
आप उनका पता कैसे लगाते हैं?
धार्मिक कोड की समीक्षा, बहु-पिरोया इकाई परीक्षण। कोई शॉर्टकट नहीं है। इस पर कुछ एक्लिप्स प्लगइन उभर रहे हैं, लेकिन अभी तक कुछ भी स्थिर नहीं है।
आप उन्हें कैसे संभालते हैं और रोकते हैं?
सबसे अच्छी बात यह होगी कि साइड-इफ़ेक्ट फ़्री और स्टेटलेस फ़ंक्शंस बनाएं, जितना संभव हो सके इम्यूलेट्स का उपयोग करें। लेकिन ऐसा हमेशा संभव नहीं है। इसलिए java.util.concurrent.atomic, समवर्ती डेटा संरचनाओं, उचित सिंक्रनाइज़ेशन और अभिनेता आधारित समरूपता का उपयोग करने में मदद मिलेगी।
सुगमता के लिए सबसे अच्छा संसाधन JCIP है। आप ऊपर दिए गए स्पष्टीकरण पर कुछ और विवरण भी प्राप्त कर सकते हैं ।
दौड़ की स्थिति और डेटा दौड़ के बीच एक महत्वपूर्ण तकनीकी अंतर है। अधिकांश उत्तर यह धारणा बनाते प्रतीत होते हैं कि ये शब्द समतुल्य हैं, लेकिन वे नहीं हैं।
एक डेटा रेस तब होती है जब 2 निर्देश एक ही मेमोरी लोकेशन को एक्सेस करते हैं, इनमें से कम से कम एक एक्सेस एक राइट होता है और इन एक्सेस के बीच ऑर्डर करने से पहले ऐसा कुछ नहीं होता है । अब ऑर्डर करने से पहले जो होता है वह बहुत बहस का विषय होता है, लेकिन सामान्य लॉक-लॉक जोड़े में एक ही लॉक वैरिएबल पर और एक ही कंडीशन के वैरिएबल पर वेट-सिग्नल जोड़े एक ऑर्डर से पहले के ऑर्डर को प्रेरित करते हैं।
एक दौड़ की स्थिति एक शब्दार्थ त्रुटि है। यह एक दोष है कि समय या घटनाओं के आदेश में होता है कि गलत कार्यक्रम के लिए सुराग व्यवहार ।
दौड़ की कई स्थितियां (और वास्तव में) डेटा दौड़ के कारण हो सकती हैं, लेकिन यह आवश्यक नहीं है। तथ्य की बात के रूप में, डेटा दौड़ और दौड़ की स्थिति न तो आवश्यक है, न ही एक दूसरे के लिए पर्याप्त स्थिति। यह ब्लॉग पोस्ट एक साधारण बैंक लेनदेन उदाहरण के साथ अंतर को भी अच्छी तरह से समझाता है। यहाँ एक और सरल उदाहरण है जो अंतर बताता है।
अब जब हमने शब्दावली को समाप्त कर दिया है, तो हम मूल प्रश्न का उत्तर देने का प्रयास करें।
यह देखते हुए कि दौड़ की स्थिति शब्दार्थ कीड़े हैं, उनका पता लगाने का कोई सामान्य तरीका नहीं है। ऐसा इसलिए है क्योंकि स्वचालित ओरेकल होने का कोई तरीका नहीं है जो सामान्य मामले में सही बनाम गलत प्रोग्राम व्यवहार को अलग कर सकता है। रेस डिटेक्शन एक असंदिग्ध समस्या है।
दूसरी ओर, डेटा दौड़ की एक सटीक परिभाषा है जो जरूरी नहीं कि शुद्धता से संबंधित हो, और इसलिए कोई भी उनका पता लगा सकता है। डेटा रेस डिटेक्टर (स्थैतिक / गतिशील डेटा रेस डिटेक्शन, लॉकसेट-आधारित डेटा रेस डिटेक्शन, होने से पहले-आधारित डेटा रेस डिटेक्शन, हाइब्रिड डेटा रेस डिटेक्शन) के कई फ्लेवर हैं। आर्ट डायनेमिक डेटा रेस डिटेक्टर की एक स्थिति थ्रेडसनीटाइज़र है जो व्यवहार में बहुत अच्छी तरह से काम करती है।
सामान्य रूप से डेटा दौड़ से निपटने के लिए कुछ प्रोग्रामिंग अनुशासन की आवश्यकता होती है ताकि साझा डेटा तक पहुंच के बीच किनारों से पहले (या तो विकास के दौरान, या एक बार उन्हें उपर्युक्त उपकरणों का उपयोग करके पता लगाया जा सके)। यह ताले, कंडीशन वैरिएबल्स, सेमाफोर आदि के माध्यम से किया जा सकता है। हालांकि, कोई व्यक्ति मैसेज पासिंग (साझा मेमोरी के बजाय) जैसे विभिन्न प्रोग्रामिंग प्रतिमानों को भी नियोजित कर सकता है जो निर्माण द्वारा डेटा रेस से बचते हैं।
एक प्रकार की विहित परिभाषा " जब दो धागे एक ही समय में स्मृति में एक ही स्थान तक पहुंचते हैं, और कम से कम एक एक्सेस एक लेखन होता है ।" इस स्थिति में "रीडर" थ्रेड को पुराना मान या नया मान मिल सकता है, जिसके आधार पर "रेस जीतता है।" यह हमेशा एक बग नहीं है - वास्तव में, कुछ वास्तव में बालों वाले निम्न-स्तर के एल्गोरिदम इस उद्देश्य से करते हैं - लेकिन इसे आमतौर पर टाला जाना चाहिए। @Steve Gury एक अच्छा उदाहरण देता है जब यह एक समस्या हो सकती है।
एक दौड़ की स्थिति एक प्रकार की बग है, जो केवल कुछ अस्थायी स्थितियों के साथ होती है।
उदाहरण: कल्पना कीजिए कि आपके दो धागे हैं, ए और बी।
थ्रेड ए में:
if( object.a != 0 )
object.avg = total / object.a
थ्रेड बी में:
object.a = 0
यदि थ्रेड ए की जांच के बाद ही यह बताया जाता है कि ऑब्जेक्ट अशक्त नहीं है, बी करेगा a = 0, और जब थ्रेड ए प्रोसेसर को प्राप्त करेगा, तो यह "शून्य से विभाजित" करेगा।
यह बग केवल तब होता है जब थ्रेड ए केवल स्टेटमेंट के बाद प्रीमेप्टेड होता है, यह बहुत दुर्लभ है, लेकिन यह हो सकता है।
रेस की स्थिति न केवल सॉफ्टवेयर से संबंधित है, बल्कि हार्डवेयर से भी संबंधित है। दरअसल यह शब्द शुरू में हार्डवेयर उद्योग द्वारा गढ़ा गया था।
विकिपीडिया के अनुसार :
यह शब्द दो संकेतों के विचार से उत्पन्न होता है जो पहले आउटपुट को प्रभावित करने के लिए एक दूसरे को रेसिंग करते हैं ।
एक तर्क सर्किट में दौड़ की स्थिति:
सॉफ्टवेयर उद्योग ने बिना संशोधन के इस शब्द को लिया, जिससे इसे समझना थोड़ा मुश्किल हो जाता है।
आपको सॉफ़्टवेयर की दुनिया में इसे बदलने के लिए कुछ प्रतिस्थापन करने की आवश्यकता है:
इसलिए सॉफ्टवेयर उद्योग में दौड़ की स्थिति का अर्थ है "दो धागे" / "दो प्रक्रियाएं" एक दूसरे को "कुछ साझा स्थिति को प्रभावित करने के लिए" रेसिंग, और साझा राज्य का अंतिम परिणाम कुछ सूक्ष्म समय अंतर पर निर्भर करेगा, जो कुछ विशिष्ट के कारण हो सकता है थ्रेड / प्रोसेस लॉन्चिंग ऑर्डर, थ्रेड / प्रोसेस शेड्यूलिंग आदि।
एक दौड़ की स्थिति समवर्ती प्रोग्रामिंग पर एक स्थिति है जहां दो समवर्ती धागे या प्रक्रियाएं संसाधन के लिए प्रतिस्पर्धा करती हैं और परिणामी अंतिम स्थिति इस बात पर निर्भर करती है कि संसाधन पहले कौन प्राप्त करता है।
बहु-थ्रेडेड एप्लिकेशन या मल्टी-प्रोसेस सिस्टम में रेस की स्थिति होती है। एक दौड़ की स्थिति, इसके सबसे मूल में, कुछ भी है जो यह धारणा बनाता है कि एक ही धागे या प्रक्रिया में दो चीजें एक विशेष क्रम में नहीं होंगी, यह सुनिश्चित करने के लिए कदम उठाए बिना कि वे करते हैं। यह आमतौर पर तब होता है जब दो धागे एक वर्ग के सदस्य चर की स्थापना और जाँच करके संदेश भेज रहे हैं जो दोनों का उपयोग कर सकते हैं। लगभग हमेशा एक दौड़ की स्थिति होती है जब एक थ्रेड किसी कार्य को पूरा करने के लिए एक और थ्रेड समय देने के लिए नींद को बुलाता है (जब तक कि नींद लूप में न हो, कुछ जाँच तंत्र के साथ)।
दौड़ की स्थिति को रोकने के लिए उपकरण भाषा और OS पर निर्भर हैं, लेकिन कुछ कॉमन वाले म्यूटेक्स, क्रिटिकल सेक्शन और सिग्नल हैं। म्यूटेक्स अच्छे होते हैं जब आप यह सुनिश्चित करना चाहते हैं कि आप केवल कुछ कर रहे हैं। सिग्नल अच्छे हैं जब आप यह सुनिश्चित करना चाहते हैं कि किसी और ने कुछ करना समाप्त कर दिया है। साझा संसाधनों को कम करने से अप्रत्याशित व्यवहार को रोकने में भी मदद मिल सकती है
दौड़ की स्थिति का पता लगाना मुश्किल हो सकता है, लेकिन कुछ संकेत हैं। कोड जो नींद पर बहुत निर्भर करता है, दौड़ की स्थिति से ग्रस्त है, इसलिए पहले प्रभावित कोड में सोने के लिए कॉल की जाँच करें। विशेष रूप से लंबी नींद जोड़ना भी डिबगिंग के लिए इस्तेमाल किया जा सकता है और घटनाओं के एक विशेष क्रम को मजबूर करने के लिए। यह व्यवहार को पुन: पेश करने के लिए उपयोगी हो सकता है, यह देखने के लिए कि क्या आप चीजों के समय को बदलकर गायब हो सकते हैं, और जगह में समाधानों के परीक्षण के लिए। डिबगिंग के बाद नींद को हटा दिया जाना चाहिए।
हस्ताक्षर संकेत है कि एक दौड़ हालत है, हालांकि, अगर वहाँ एक समस्या है कि केवल कुछ मशीनों पर रुक-रुक कर होती है। सामान्य बग क्रैश और गतिरोध होंगे। लॉगिंग के साथ, आपको प्रभावित क्षेत्र को खोजने और वहां से वापस काम करने में सक्षम होना चाहिए।
Microsoft ने वास्तव में दौड़ की स्थिति और गतिरोध के इस मामले पर एक बहुत विस्तृत लेख प्रकाशित किया है । इसमें से सबसे संक्षेप सार शीर्षक पैराग्राफ होगा:
एक दौड़ की स्थिति तब होती है जब दो धागे एक ही समय में एक साझा चर का उपयोग करते हैं। पहला धागा चर को पढ़ता है, और दूसरा धागा चर से समान मूल्य को पढ़ता है। फिर पहला धागा और दूसरा धागा मूल्य पर अपना संचालन करते हैं, और वे यह देखने के लिए दौड़ते हैं कि कौन सा धागा साझा चर पर अंतिम मान लिख सकता है। थ्रेड का मान जो उसके मान को अंतिम रूप से लिखता है, वह संरक्षित है, क्योंकि थ्रेड उस मान पर लिख रहा है, जो पिछले थ्रेड ने लिखा था।
एक दौड़ की स्थिति क्या है?
वह स्थिति जब प्रक्रिया गंभीर रूप से अन्य घटनाओं के अनुक्रम या समय पर निर्भर होती है।
उदाहरण के लिए, प्रोसेसर ए और प्रोसेसर बी दोनों को उनके निष्पादन के लिए समान संसाधन की आवश्यकता है ।
आप उनका पता कैसे लगाते हैं?
स्वचालित रूप से दौड़ की स्थिति का पता लगाने के लिए उपकरण हैं:
आप उन्हें कैसे संभालेंगे?
रेस स्थिति से संभाला जा सकता है Mutex या Semaphores । वे एक ताला के रूप में कार्य करते हैं जो रेस की स्थिति को रोकने के लिए एक प्रक्रिया को कुछ आवश्यकताओं के आधार पर संसाधन प्राप्त करने की अनुमति देता है।
आप उन्हें होने से कैसे रोकेंगे?
दौड़ की स्थिति को रोकने के लिए विभिन्न तरीके हैं, जैसे कि महत्वपूर्ण धारा से बचाव ।
एक दौड़ की स्थिति एक अवांछनीय स्थिति है जो तब होती है जब कोई उपकरण या सिस्टम एक ही समय में दो या दो से अधिक ऑपरेशन करने का प्रयास करता है, लेकिन डिवाइस या सिस्टम की प्रकृति के कारण, संचालन उचित क्रम में किया जाना चाहिए सही ढंग से किया
कंप्यूटर मेमोरी या स्टोरेज में, एक दौड़ की स्थिति हो सकती है यदि बड़ी मात्रा में डेटा को पढ़ने और लिखने की आज्ञा लगभग एक ही समय में प्राप्त होती है, और मशीन पुराने डेटा अभी भी कुछ या सभी पुराने डेटा को अधिलेखित करने का प्रयास करती है। पढ़ें। परिणाम निम्न में से एक या अधिक हो सकता है: एक कंप्यूटर दुर्घटना, एक "अवैध संचालन," अधिसूचना और कार्यक्रम का बंद होना, पुराने डेटा को पढ़ने में त्रुटियां, या नए डेटा लिखने में त्रुटियां।
यहाँ शास्त्रीय बैंक खाता शेष उदाहरण दिया गया है जो जावा में थ्रेड्स को आसानी से समझने के लिए newbies को रेस की स्थितियों में मदद करेगा:
public class BankAccount {
/**
* @param args
*/
int accountNumber;
double accountBalance;
public synchronized boolean Deposit(double amount){
double newAccountBalance=0;
if(amount<=0){
return false;
}
else {
newAccountBalance = accountBalance+amount;
accountBalance=newAccountBalance;
return true;
}
}
public synchronized boolean Withdraw(double amount){
double newAccountBalance=0;
if(amount>accountBalance){
return false;
}
else{
newAccountBalance = accountBalance-amount;
accountBalance=newAccountBalance;
return true;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BankAccount b = new BankAccount();
b.accountBalance=2000;
System.out.println(b.Withdraw(3000));
}
आप दौड़ की स्थिति को रोक सकते हैं , यदि आप "परमाणु" वर्गों का उपयोग करते हैं। कारण सिर्फ इतना है कि थ्रेड अलग-अलग ऑपरेशन नहीं करते और सेट करते हैं, उदाहरण नीचे है:
AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);
नतीजतन, आपके पास लिंक "एआई" में 7 होंगे। हालाँकि आपने दो क्रियाएं की थीं, लेकिन दोनों ऑपरेशन एक ही धागे की पुष्टि करते हैं और कोई भी अन्य धागा इस पर हस्तक्षेप नहीं करेगा, इसका मतलब है कि कोई दौड़ की स्थिति नहीं है!
दौड़ की स्थिति की बेहतर समझ के लिए इस मूल उदाहरण का प्रयास करें:
public class ThreadRaceCondition {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Account myAccount = new Account(22222222);
// Expected deposit: 250
for (int i = 0; i < 50; i++) {
Transaction t = new Transaction(myAccount,
Transaction.TransactionType.DEPOSIT, 5.00);
t.start();
}
// Expected withdrawal: 50
for (int i = 0; i < 50; i++) {
Transaction t = new Transaction(myAccount,
Transaction.TransactionType.WITHDRAW, 1.00);
t.start();
}
// Temporary sleep to ensure all threads are completed. Don't use in
// realworld :-)
Thread.sleep(1000);
// Expected account balance is 200
System.out.println("Final Account Balance: "
+ myAccount.getAccountBalance());
}
}
class Transaction extends Thread {
public static enum TransactionType {
DEPOSIT(1), WITHDRAW(2);
private int value;
private TransactionType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
};
private TransactionType transactionType;
private Account account;
private double amount;
/*
* If transactionType == 1, deposit else if transactionType == 2 withdraw
*/
public Transaction(Account account, TransactionType transactionType,
double amount) {
this.transactionType = transactionType;
this.account = account;
this.amount = amount;
}
public void run() {
switch (this.transactionType) {
case DEPOSIT:
deposit();
printBalance();
break;
case WITHDRAW:
withdraw();
printBalance();
break;
default:
System.out.println("NOT A VALID TRANSACTION");
}
;
}
public void deposit() {
this.account.deposit(this.amount);
}
public void withdraw() {
this.account.withdraw(amount);
}
public void printBalance() {
System.out.println(Thread.currentThread().getName()
+ " : TransactionType: " + this.transactionType + ", Amount: "
+ this.amount);
System.out.println("Account Balance: "
+ this.account.getAccountBalance());
}
}
class Account {
private int accountNumber;
private double accountBalance;
public int getAccountNumber() {
return accountNumber;
}
public double getAccountBalance() {
return accountBalance;
}
public Account(int accountNumber) {
this.accountNumber = accountNumber;
}
// If this method is not synchronized, you will see race condition on
// Remove syncronized keyword to see race condition
public synchronized boolean deposit(double amount) {
if (amount < 0) {
return false;
} else {
accountBalance = accountBalance + amount;
return true;
}
}
// If this method is not synchronized, you will see race condition on
// Remove syncronized keyword to see race condition
public synchronized boolean withdraw(double amount) {
if (amount > accountBalance) {
return false;
} else {
accountBalance = accountBalance - amount;
return true;
}
}
}
आप हमेशा एक दौड़ की स्थिति को त्यागना नहीं चाहते हैं। यदि आपके पास एक ध्वज है जिसे कई थ्रेड द्वारा पढ़ा और लिखा जा सकता है, और यह ध्वज एक थ्रेड द्वारा 'किया' जाता है, ताकि जब ध्वज 'सेट' पर सेट हो जाए तो अन्य थ्रेड प्रसंस्करण बंद हो जाए, आप नहीं चाहते कि "रेस हालत "समाप्त किया जाना है। वास्तव में, यह एक सौम्य दौड़ की स्थिति के रूप में संदर्भित किया जा सकता है।
हालांकि, दौड़ की स्थिति का पता लगाने के लिए एक उपकरण का उपयोग करके, इसे हानिकारक दौड़ की स्थिति के रूप में देखा जाएगा।
रेस स्थिति यहां पर अधिक जानकारी, http://msdn.microsoft.com/en-us/magazine/cc546569.aspx ।
एक ऑपरेशन पर विचार करें, जिसे गणना में वृद्धि के रूप में जल्द ही प्रदर्शित करना है। यानी।, जैसे ही काउंटरथ्रेड मूल्य बढ़ाता है DisplayThread को हाल ही में अपडेट किए गए मूल्य को प्रदर्शित करने की आवश्यकता होती है।
int i = 0;
उत्पादन
CounterThread -> i = 1
DisplayThread -> i = 1
CounterThread -> i = 2
CounterThread -> i = 3
CounterThread -> i = 4
DisplayThread -> i = 4
यहाँ CounterThread को बार-बार लॉक मिलता है और DisplayThread को प्रदर्शित करने से पहले मान को अद्यतन करता है। यहाँ एक रेस कंडीशन मौजूद है। Synchronzation का उपयोग करके रेस कंडीशन को हल किया जा सकता है
एक दौड़ की स्थिति एक अवांछनीय स्थिति है जो तब होती है जब दो या अधिक प्रक्रिया एक ही समय में साझा किए गए डेटा तक पहुंच सकते हैं और बदल सकते हैं। ऐसा इसलिए हुआ क्योंकि एक संसाधन के लिए परस्पर विरोधी एक्सेस थे। गंभीर स्थिति समस्या दौड़ की स्थिति का कारण बन सकती है। प्रक्रिया के बीच गंभीर स्थिति को हल करने के लिए हम एक समय में केवल एक प्रक्रिया को निकालते हैं जो महत्वपूर्ण अनुभाग को निष्पादित करता है।