7

मुझे संबंधों के साथ सिंक्रनाइज़ करने में मदद की ज़रूरत है। जितना अधिक मैं इसे समझने की कोशिश कर रहा हूं, उतना ही मुझे लगता है कि मैं कुछ भी नहीं समझता। कभी-कभी मुझे लगता है कि यह है, मुझे मिल गया है, लेकिन एक और उदाहरण देखने के बाद मैं फिर से उलझन में आ गया। कृपया इसे सही करने में मेरी मदद करें।सिंक्रनाइज़ करता है-साथ, संबंध और अधिग्रहण से पहले सेमेन्टिक्स

ऐसा कहा जाता है कि एक ऑपरेशन ए एक सिंक्रनाइज़ करता है- एक ऑपरेशन बी के साथ अगर ए कुछ रिलीज सेमेन्टिक्स के साथ कुछ परमाणु चर एम के लिए एक स्टोर है, बी एक ही चर से एम है, अर्थात् अधिग्रहण के साथ, और बी मान को पढ़ता है ए द्वारा संग्रहीत यह भी कहा जाता है कि एक ऑपरेशन एक होता है-पहले एक ऑपरेशन बी अगर

  • एक बी के रूप में ही धागे पर, या
  • एक सिंक्रनाइज़ किया जाता है, और एक कार्यक्रम के क्रम में बी से पहले है -साथ बी, या
  • कोई अन्य ऑपरेशन सी से पहले होता है, और सी होता है-बी
  • 01 से पहले

ठीक है। अगर हम इस उदाहरण को देखते हैं

thread0 प्रदर्शन करता है | thread1


स्टोर x (रिलीज़) | लोड एक्स (अधिग्रहण)

एक्स से लोड के साथ एक्स को सिंक्रनाइज़ करने के लिए यहां स्टोर करता है? अगर हम यहां रिश्ते के साथ सिंक्रनाइज़ करते हैं, तो एक्स से लोड करने से पहले एक्स को स्टोर किया जाता है, इसलिए थ्रेड में x से पहले स्टोर में अनुक्रमित होने वाली प्रत्येक चीज 0 से पहले थ्रेड में लोड होने से पहले होती है। इसका मतलब है कि यहां लागू ऑर्डर किया गया है। क्या यह सही है? लेकिन इस मामले में मुझे समझ में नहीं आता कि "और बी परिभाषा के हिस्से" ए द्वारा संग्रहीत मूल्य को क्या पढ़ता है? यदि थ्रेड 1 तेज है तो थ्रेड 0 यह पुराना मान पढ़ सकता है। तो यहां रिश्ता क्या है और क्या कोई रिश्ता है? यदि कोई नहीं है, तो मैं उस रिश्ते को कैसे प्रदान कर सकता हूं?

अग्रिम धन्यवाद।

+0

एक महान लेख यहाँ है http://preshing.com/20130823/the-synchronizes-with-relation/ – camino

उत्तर

4

मैं यह नहीं कह सकता कि मैं शब्दावली से अच्छी तरह से परिचित हूं, लेकिन इस तरह मुझे लगता है कि यह जाता है। मैं शर्तों के लिए .NET परिभाषाओं का उपयोग करूंगा: "एक ऑपरेशन ने अर्थशास्त्र प्राप्त किया है यदि अन्य प्रोसेसर हमेशा किसी भी ऑपरेशन के प्रभाव से पहले इसका प्रभाव देखेंगे। एक ऑपरेशन ने सेमेन्टिक्स जारी किया है यदि अन्य प्रोसेसर प्रत्येक पूर्ववर्ती ऑपरेशन के प्रभाव को पहले के प्रभाव से पहले देखेंगे ऑपरेशन स्वयं। "

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

हालांकि, लोड ऑपरेशन स्टोर से पहले निष्पादित किया जा सकता है। उस स्थिति में ए सिंक्रनाइज़ नहीं करता है-बी के साथ (शर्त "और बी ए द्वारा संग्रहीत मान को पढ़ता है" सत्य नहीं है) और इसलिए लोड के बाद ऑपरेशन को स्टोर से पहले के संचालन से पहले निष्पादित किया जा सकता है। आदेश अस्पष्ट है।

रिलीज सेमेन्टिक्स गारंटी देता है कि एक्स के कुछ मूल्य के लिए हम जानते होंगे कि स्टोर से पहले के संचालन को पहले थ्रेड में उसी संग्रहित मूल्य को लोड करने में सक्षम होने से पहले निष्पादित किया जाएगा (और इससे पहले कि हम संचालन निष्पादित कर सकें भार के बाद)।

thread0: 
st   count, 1 (A) 
st.release flag, 1 (B) 

thread1: 
ld.acquire flag  (C) 
ld   count  (D) 

हम जानते हैं कि एक होता है-पहले बी और सी होता है-पहले डी, क्योंकि उनके आदेश से मजबूर किया जाता है:

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

थ्रेड 1 में ध्वज 1 होता है तो ध्वज 1 होता है। यदि ध्वज 0 है तो गिनती 0 या 1 हो सकती है। हम यह निर्धारित करने के लिए ध्वज का परीक्षण कर सकते हैं कि अन्य थ्रेड ने मूल्य को गिनने के लिए निर्धारित किया है या नहीं।

अर्थशास्त्र प्राप्त करने और रिलीज किए बिना लोड और स्टोर को फिर से व्यवस्थित किया जा सकता है और ध्वज और गिनती दोनों या तो 0 या 1 हो सकती हैं, जिसमें एक दूसरे के प्रति निर्भरता नहीं होती है।

यदि हम यह सुनिश्चित करना चाहते हैं कि बी सी से पहले होता है, तो हम सेमफोर या कुछ अन्य प्रतीक्षा-सिग्नल तंत्र का उपयोग कर सकते हैं। पिछले उदाहरण में हम झंडे को सेट करने के लिए व्यस्त-प्रतीक्षा करके आदेश को लागू कर सकते थे।

thread1: 
ld.acquire flag  (C) 
repeat C while flag == 0 
ld   count  (D) 
संबंधित मुद्दे