मुझे अक्सर ये शब्द समवर्ती प्रोग्रामिंग के संदर्भ में उपयोग किए जाते हैं। क्या वे एक ही चीज हैं या अलग हैं?
जवाबों:
नहीं, वे एक ही चीज नहीं हैं। वे एक दूसरे के उप-समूह नहीं हैं। वे न तो आवश्यक हैं, न ही एक दूसरे के लिए पर्याप्त स्थिति।
डेटा रेस की परिभाषा बहुत स्पष्ट है, और इसलिए, इसकी खोज स्वचालित हो सकती है। एक डेटा रेस तब होती है जब विभिन्न थ्रेड्स से 2 निर्देश एक ही मेमोरी लोकेशन तक पहुंचते हैं, इनमें से कम से कम एक एक्सेस एक राइट होता है और ऐसा कोई सिंक्रोनाइज़ेशन नहीं होता है जो इन एक्सेस के बीच किसी विशेष ऑर्डर को अनिवार्य कर रहा हो ।
एक दौड़ की स्थिति एक शब्दार्थ त्रुटि है। यह एक दोष है जो समय या घटनाओं के क्रम में होता है जो गलत प्रोग्राम व्यवहार की ओर जाता है। कई दौड़ की स्थिति डेटा दौड़ के कारण हो सकती है, लेकिन यह आवश्यक नहीं है।
निम्नलिखित सरल उदाहरण पर विचार करें जहां x एक साझा चर है:
Thread 1 Thread 2
lock(l) lock(l)
x=1 x=2
unlock(l) unlock(l)
इस उदाहरण में, थ्रेड 1 और 2 से x को ताले द्वारा संरक्षित किया जाता है, इसलिए वे हमेशा कुछ क्रम में घटित होते हैं, जिस क्रम से ताले क्रम में प्राप्त किए जाते हैं। यही है, लिखता है 'परमाणु नहीं तोड़ा जा सकता है; किसी भी निष्पादन में दोनों के बीच संबंध होने से पहले हमेशा कुछ होता है। हम सिर्फ यह नहीं जान सकते हैं कि जो लिखना है वह एक प्राथमिकता से पहले होता है।
राइट्स के बीच कोई निश्चित ऑर्डर नहीं है, क्योंकि ताले इसे प्रदान नहीं कर सकते हैं। यदि प्रोग्राम की शुद्धता के साथ छेड़छाड़ की जाती है, तो यह कहें कि जब थ्रेड टू x बाय थ्रेड 2 के बाद राइट टू x थ्रेड 1 में लिखा जाए, तो हम कहते हैं कि रेस की स्थिति है, हालाँकि तकनीकी रूप से कोई डेटा रेस नहीं है।
डेटा दौड़ की तुलना में दौड़ की स्थिति का पता लगाना कहीं अधिक उपयोगी है; हालाँकि इसे हासिल करना भी बहुत मुश्किल है।
रिवर्स उदाहरण का निर्माण भी तुच्छ है। यह ब्लॉग पोस्ट एक साधारण बैंक लेनदेन उदाहरण के साथ अंतर को भी अच्छी तरह से समझाता है।
विकिपीडिया के अनुसार, "दौड़ की स्थिति" शब्द पहले इलेक्ट्रॉनिक लॉजिक गेट्स के दिनों से उपयोग में है। जावा के संदर्भ में, एक दौड़ की स्थिति किसी भी संसाधन से संबंधित हो सकती है, जैसे कि फ़ाइल, नेटवर्क कनेक्शन, थ्रेड पूल से एक धागा आदि।
शब्द "डेटा रेस" जेएलएस द्वारा परिभाषित अपने विशिष्ट अर्थ के लिए सबसे अच्छा आरक्षित है ।
सबसे दिलचस्प मामला एक दौड़ की स्थिति है जो डेटा रेस के समान है, लेकिन अभी भी एक नहीं है, जैसे इस सरल उदाहरण में:
class Race {
static volatile int i;
static int uniqueInt() { return i++; }
}
चूंकि i
अस्थिर है, कोई डेटा दौड़ नहीं है; हालाँकि, प्रोग्राम की शुद्धता के दृष्टिकोण से दो ऑपरेशनों की गैर-परमाणुता के कारण एक दौड़ की स्थिति है: पढ़ना i
, लिखना i+1
। एकाधिक थ्रेड से समान मान प्राप्त हो सकता है uniqueInt
।
data race
वास्तव में JLS में क्या मतलब है?
नहीं, वे अलग-अलग हैं और दोनों में से कोई भी एक या इसके विपरीत का उपसमूह नहीं है।
शब्द रेस की स्थिति अक्सर संबंधित शब्द डेटा रेस के साथ भ्रमित होती है, जो तब उत्पन्न होती है जब किसी साझा नॉनफ़ाइनल फ़ील्ड में सभी एक्सेस को समन्वय करने के लिए सिंक्रनाइज़ेशन का उपयोग नहीं किया जाता है। आप एक डेटा रेस को जोखिम में डालते हैं जब भी एक थ्रेड एक वैरिएबल लिखते हैं जो कि अगले थ्रेड द्वारा पढ़ा जा सकता है या एक वैरिएबल पढ़ता है जो शायद आखिरी बार दूसरे थ्रेड द्वारा लिखा गया हो अगर दोनों थ्रेड्स सिंक्रोनाइज़ेशन का उपयोग नहीं करते हैं; डेटा दौड़ के साथ कोड में जावा मेमोरी मॉडल के तहत कोई उपयोगी परिभाषित शब्दार्थ नहीं है। सभी रेस स्थितियां डेटा रेस नहीं हैं, और सभी डेटा रेस रेस की स्थिति नहीं हैं, लेकिन वे दोनों अप्रत्याशित कार्यक्रमों को अप्रत्याशित तरीकों से विफल कर सकते हैं।
उत्कृष्ट पुस्तक से लिया गया - यहोशू बलोच एंड कंपनी द्वारा प्रैक्टिस में जावा कॉनएरेमरी
टीएल; डीआर: डेटा दौड़ और दौड़ की स्थिति के बीच का अंतर समस्या निर्माण की प्रकृति पर निर्भर करता है, और अपरिभाषित व्यवहार और अच्छी तरह से परिभाषित लेकिन अनिश्चित व्यवहार के बीच सीमा को कहां खींचना है। वर्तमान अंतर पारंपरिक है और प्रोसेसर वास्तुकार और प्रोग्रामिंग भाषा के बीच इंटरफेस को दर्शाता है।
1. शब्दार्थ
डेटा दौड़ विशेष रूप से गैर-सिंक्रनाइज़ किए गए परस्पर विरोधी "मेमोरी एक्सेस" (या क्रियाएं, या संचालन) को समान मेमोरी स्थान पर संदर्भित करती है। यदि मेमोरी एक्सेस में कोई संघर्ष नहीं है, जबकि ऑपरेशन ऑर्डरिंग के कारण अभी भी अनिश्चित व्यवहार है, तो यह एक दौड़ की स्थिति है।
नोट "मेमोरी एक्सेस" का यहाँ विशिष्ट अर्थ है। वे "शुद्ध" मेमोरी लोड या स्टोर क्रियाओं को संदर्भित करते हैं, बिना किसी अतिरिक्त शब्दार्थ के। उदाहरण के लिए, एक थ्रेड से एक मेमोरी स्टोर (आवश्यक रूप से) यह नहीं जानता कि डेटा को मेमोरी में लिखे जाने में कितना समय लगता है, और अंत में दूसरे धागे का प्रचार करता है। एक अन्य उदाहरण के लिए, एक मेमोरी स्टोर एक स्थान से दूसरे स्टोर से पहले एक ही स्थान द्वारा एक ही थ्रेड द्वारा (आवश्यक रूप से) मेमोरी में लिखे गए पहले डेटा को दूसरे से आगे रहने की गारंटी नहीं देता है। नतीजतन, उन शुद्ध मेमोरी एक्सेस का क्रम "तर्कपूर्ण" होने में सक्षम (आवश्यक) नहीं है , और कुछ भी हो सकता है, जब तक कि अन्यथा अच्छी तरह से परिभाषित न हो।
जब "मेमोरी एक्सेस" को सिंक्रनाइज़ेशन के माध्यम से ऑर्डर करने के संदर्भ में अच्छी तरह से परिभाषित किया गया है, तो अतिरिक्त शब्दार्थ यह सुनिश्चित कर सकते हैं कि, भले ही मेमोरी एक्सेस की समय सीमा अनिश्चित हो, उनके आदेश को सिंक्रोनाइज़ेशन के माध्यम से "तर्क" किया जा सकता है । ध्यान दें, यद्यपि मेमोरी एक्सेस के बीच ऑर्डर को तर्क दिया जा सकता है, लेकिन वे आवश्यक रूप से निर्धारित नहीं होते हैं, इसलिए दौड़ की स्थिति।
2. अंतर क्यों?
लेकिन अगर आदेश अभी भी दौड़ की स्थिति में अनिश्चित है, तो इसे डेटा रेस से अलग करने की जहमत क्यों? कारण सैद्धांतिक के बजाय व्यावहारिक में है। इसका कारण यह है कि प्रोग्रामिंग भाषा और प्रोसेसर आर्किटेक्चर के बीच इंटरफेस में अंतर मौजूद है।
आधुनिक वास्तुकला में एक मेमोरी लोड / स्टोर निर्देश आमतौर पर "शुद्ध" मेमोरी एक्सेस के रूप में लागू किया जाता है, आउट-ऑफ-ऑर्डर पाइपलाइन की प्रकृति के कारण, अटकलें, कैश का बहु-स्तर, सीपीयू-रैम इंटरकनेक्शन, विशेष रूप से मल्टी-कोर, आदि। वहाँ बहुत सारे कारक हैं जो अनिश्चित समय और आदेश देने के लिए अग्रणी हैं। हर मेमोरी इंस्ट्रक्शन के लिए ऑर्डर देने पर भारी जुर्माना लगाया जाता है, खासकर प्रोसेसर डिजाइन में जो मल्टी-कोर का समर्थन करता है। अतः विभिन्न प्रकार की बाधाओं (या बाड़) जैसे अतिरिक्त निर्देशों के साथ क्रमबद्ध शब्दार्थ प्रदान किए जाते हैं।
डेटा रेस परस्पर विरोधी स्मृति अभिगम के क्रम को तर्क देने में मदद करने के लिए अतिरिक्त बाड़ के बिना प्रोसेसर निर्देश निष्पादन की स्थिति है। परिणाम न केवल अनिश्चित है, बल्कि संभवतः बहुत ही अजीब है, उदाहरण के लिए, दो अलग-अलग थ्रेड द्वारा एक ही शब्द स्थान पर लिखते हैं, जिसके परिणामस्वरूप प्रत्येक शब्द आधा शब्द लिख सकता है, या केवल उनके स्थानीय रूप से कैश्ड मानों पर काम कर सकता है। - ये अपरिभाषित व्यवहार हैं, प्रोग्रामर के दृष्टिकोण से। लेकिन वे (आमतौर पर) प्रोसेसर वास्तुकार के दृष्टिकोण से अच्छी तरह से परिभाषित हैं।
प्रोग्रामर्स के लिए एक रास्ता होना चाहिए कारण उनके कोड निष्पादन। डेटा की दौड़ कुछ ऐसी है जिससे वे समझ नहीं सकते हैं, इसलिए हमेशा (सामान्य रूप से) बचना चाहिए। यही कारण है कि भाषा विनिर्देश जो निम्न स्तर के होते हैं, आमतौर पर डेटा रेस को अपरिभाषित व्यवहार के रूप में परिभाषित करते हैं, रेस स्थिति के अच्छी तरह से परिभाषित स्मृति व्यवहार से अलग होते हैं।
3. भाषा स्मृति मॉडल
विभिन्न प्रोसेसरों में अलग मेमोरी एक्सेस व्यवहार हो सकता है, अर्थात प्रोसेसर मेमोरी मॉडल। प्रोग्रामर के लिए हर आधुनिक प्रोसेसर के मेमोरी मॉडल का अध्ययन करना और फिर उन कार्यक्रमों को विकसित करना अजीब है जो उनसे लाभ उठा सकते हैं। यह वांछनीय है अगर भाषा एक मेमोरी मॉडल को परिभाषित कर सकती है ताकि उस भाषा के कार्यक्रम हमेशा उसी तरह व्यवहार करें जैसे कि स्मृति मॉडल परिभाषित करता है। यही कारण है कि जावा और सी ++ में उनके मेमोरी मॉडल परिभाषित हैं। यह सुनिश्चित करने के लिए कंपाइलर / रनटाइम डेवलपर्स का बोझ है कि भाषा मेमोरी मॉडल को विभिन्न प्रोसेसर आर्किटेक्चर में लागू किया जाए।
उस ने कहा, अगर कोई भाषा प्रोसेसर के निम्न स्तर के व्यवहार को उजागर नहीं करना चाहती (और आधुनिक आर्किटेक्चर के कुछ प्रदर्शन लाभ का त्याग करने के लिए तैयार है), वे एक मेमोरी मॉडल को परिभाषित करने का विकल्प चुन सकते हैं जो "शुद्ध" के विवरण को पूरी तरह से छिपा देता है। मेमोरी एक्सेस, लेकिन उनके सभी मेमोरी ऑपरेशंस के लिए ऑर्डरिंग सिमेंटिक्स लागू करें। तब कंपाइलर / रनटाइम डेवलपर्स हर मेमोरी चर को सभी प्रोसेसर आर्किटेक्चर में अस्थिर के रूप में मान सकते हैं। इन भाषाओं के लिए (जो थ्रेड्स में साझा मेमोरी का समर्थन करते हैं), कोई डेटा दौड़ नहीं है, लेकिन फिर भी दौड़ की स्थिति हो सकती है, यहां तक कि पूर्ण अनुक्रमिक समता की भाषा के साथ।
दूसरी ओर, प्रोसेसर मेमोरी मॉडल सख्त (या कम आराम या उच्च स्तर पर) हो सकता है, उदाहरण के लिए, शुरुआती दिनों के रूप में अनुक्रमिक स्थिरता को लागू करना। फिर सभी मेमोरी ऑपरेशन का आदेश दिया जाता है, और प्रोसेसर में चलने वाली किसी भी भाषा के लिए कोई डेटा रेस मौजूद नहीं है।
4। निष्कर्ष
मूल प्रश्न पर वापस, IMHO डेटा रेस को रेस की स्थिति के विशेष मामले के रूप में परिभाषित करना ठीक है, और एक स्तर पर रेस की स्थिति उच्च स्तर पर डेटा रेस बन सकती है। यह समस्या निर्माण की प्रकृति पर निर्भर करता है, और अपरिभाषित व्यवहार और अच्छी तरह से परिभाषित लेकिन अनिश्चित व्यवहार के बीच सीमा को कहां खींचना है। बस वर्तमान सम्मेलन भाषा-प्रोसेसर इंटरफ़ेस पर सीमा को परिभाषित करता है, जरूरी नहीं कि हमेशा ऐसा हो और ऐसा ही हो; लेकिन वर्तमान सम्मेलन शायद प्रोसेसर वास्तुकार और प्रोग्रामिंग भाषा के बीच अत्याधुनिक इंटरफ़ेस (और ज्ञान) को दर्शाता है।