2011-08-30 14 views
5

इस सूत्रण ऑनलाइन पुस्तक में: http://www.albahari.com/threading/part4.aspxसमझौता गैर अवरुद्ध धागा तुल्यकालन और Thread.MemoryBarrier

Thread.MemoryBarrier()

class Foo 
{ 
    int _answer; 
    bool _complete; 

    void A() 
    { 
    _answer = 123; 
    Thread.MemoryBarrier(); // Barrier 1 
    _complete = true; 
    Thread.MemoryBarrier(); // Barrier 2 
    } 

    void B() 
    { 
    Thread.MemoryBarrier(); // Barrier 3 
    if (_complete) 
    { 
     Thread.MemoryBarrier();  // Barrier 4 
     Console.WriteLine (_answer); 
    } 
    } 
} 

का एक उदाहरण theres हम एक चर्चा है कि क्या वहाँ है किसी भी धागा अवरुद्ध पर या नहीं जा रहा है?

इम सोच वहाँ कुछ है, खासकर यह देखते हुए कि

एक पूर्ण बाड़ एक 2010 युग डेस्कटॉप पर लगभग दस नैनोसेकंड लेता है।

दूसरी ओर, पूर्ण बाड़ केवल disable instructions reodering and caching को, lock के विपरीत माना जाता है जो अपनी आवाज से धागा अवरुद्ध के रूप में योग्य नहीं है (जहां इसकी स्पष्ट है कि के लिए धागा प्रतीक्षा करता है ताला जारी करने के लिए इससे पहले कि यह जारी है, और अवरुद्ध है अन्य उस समय के दौरान)

उस धागे के बारे में 'ब्लॉक स्थिति'। मैं को अवरुद्ध कर दिया गया है या नहीं, लेकिन क्या थ्रेड सिंक्रनाइज़ेशन हो रहा है या नहीं, इसका मतलब है कि एक थ्रेड चलाने में सक्षम नहीं है, जबकि अन्य इसे ऐसा करने की अनुमति नहीं दे रहा है, इस मामले में मेमोरीबैरियर।

भी आईडी को समझने की इच्छा है कि प्रत्येक बाधा क्या प्राप्त करती है। उदाहरण के लिए बैरियर 2 - यह वास्तव में ताजगी गारंटी प्रदान करता है और यह बाधा 3 से कैसे जुड़ा हुआ है? यदि कोई विस्तार से समझाएगा कि प्रत्येक बाधा उद्देश्य क्या है (यदि 1 या 2 या 3 या 4 वहां नहीं थे तो संभवतः गलत क्या हो सकता है) मुझे लगता है कि आईडी इस बारे में मेरी समझ में सुधार करती है।

संपादित करें: इसके ज्यादातर अब स्पष्ट क्या 1, 2, और 3 है। हालांकि वह 4 क्या करता है जो अभी भी अस्पष्ट नहीं है।

उत्तर

5

तथ्य यह है कि निर्देशों को निष्पादित करने में समय लगता है नहीं है कि एक धागा अवरुद्ध है। एक थ्रेड अवरुद्ध होता है जब इसे विशेष रूप से अवरुद्ध स्थिति में रखा जाता है, जो MemoryBarrier() नहीं करता है।

प्रोसेसर निर्देश जो वास्तव में निर्देश पुनर्निर्माण और कैश फ्लशिंग को रोकते हैं, समय लेते हैं, क्योंकि उन्हें कैश को फिर से सुसंगत होने की प्रतीक्षा करनी चाहिए। उस समय के दौरान, धागा अभी भी चल रहा माना जाता है।

अद्यतन: तो आइए देखें कि वास्तव में उदाहरण में क्या हो रहा है, और प्रत्येक मेमोरी बाधा वास्तव में क्या करती है।

जैसा कि लिंक कहता है, 1 और 4 सुनिश्चित करता है कि सही उत्तरों का उत्पादन किया जाता है। ऐसा इसलिए है क्योंकि 1 सुनिश्चित करता है कि उत्तर स्मृति में फंस गए हैं, और 4 सुनिश्चित करता है कि चर को पुनर्प्राप्त करने से पहले पढ़ने वाले कैश फ़्लश किए जाते हैं।

2 और 3 सुनिश्चित करना है कि अगर A रन पहले, तो B होगा हमेशा प्रिंट जवाब। बैरियर 2 सुनिश्चित करता है कि true का लेखन स्मृति में फ़्लश किया गया है, और बाधा 3 सुनिश्चित करता है कि _complete के मूल्य का परीक्षण करने से पहले पढ़ने वाली कहानियों को फ़्लश किया जाता है।

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

+0

सुनिश्चित करें कि यह सीधे इसका अर्थ नहीं है, मैंने सोचा कि इसे सबूत के रूप में माना जा सकता है, यह तार्किक है कि कमांड को निष्पादित करने में समय लगता है। –

+0

@ वैलेंटिन इसे सबूत माना जा सकता है, लेकिन यह सिर्फ मामला नहीं है :) – dlev

+0

ठीक है, प्रश्न के अंत में मेरा संपादन देखें, और जब हम इसमें हों, तो लॉक स्टेटमेंट अवरुद्ध स्थिति में थ्रेड डालता है (बस स्पष्टीकरण के लिए उस धागे ने राज्य परिभाषा को अवरुद्ध कर दिया)? –

संबंधित मुद्दे