2013-11-15 5 views
70

हाल ही में मैं .NET Hashtable के कार्यान्वयन को पढ़ रहा था और मुझे समझ में नहीं आया कोड का टुकड़ा सामना करना पड़ा। कोड का हिस्सा है:.NET आंतरिक हैशटेबल में थ्रेड स्लीप (1) क्यों है?

int num3 = 0; 
int num4; 
do 
{ 
    num4 = this.version; 
    bucket = bucketArray[index]; 
    if (++num3 % 8 == 0) 
    Thread.Sleep(1); 
} 
while (this.isWriterInProgress || num4 != this.version); 

पूरे कोड System.Collections.Hashtable की public virtual object this[object key] (mscorlib संस्करण = 4.0.0.0) के भीतर है।

सवाल यह है:

Thread.Sleep(1) वहाँ होने का कारण क्या है?

+7

एक संदर्भ स्विच से पहले एक स्पिनवाइट की तरह दिखता है। अर्थात। यह थ्रेड को सोने से पहले 8 बार एक शर्त के लिए जांचता है। – Groo

+4

[इसी तरह के थ्रेड] (http://stackoverflow.com/questions/508208/what-is-the-impact-of-thread-sleep1-in-c); क्रूक्स ओएस को अन्य कार्य निर्धारित करने की अनुमति देना है – Konstantin

उत्तर

70

नींद (1) प्रोसेसर उत्पन्न करने और अन्य थ्रेड चलाने की अनुमति देने के लिए विंडोज़ में एक दस्तावेज तरीका है। आप टिप्पणी के साथ संदर्भ स्रोत में इस कोड को पा सकते हैं:

// Our memory model guarantee if we pick up the change in bucket from another processor, 
    // we will see the 'isWriterProgress' flag to be true or 'version' is changed in the reader. 
    // 
    int spinCount = 0; 
    do { 
     // this is violate read, following memory accesses can not be moved ahead of it. 
     currentversion = version; 
     b = lbuckets[bucketNumber]; 

     // The contention between reader and writer shouldn't happen frequently. 
     // But just in case this will burn CPU, yield the control of CPU if we spinned a few times. 
     // 8 is just a random number I pick. 
     if((++spinCount) % 8 == 0) { 
      Thread.Sleep(1); // 1 means we are yeilding control to all threads, including low-priority ones. 
     } 
    } while (isWriterInProgress || (currentversion != version)); 

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

+7

मैंने सोचा कि अगर आप केवल उपज चाहते हैं तो 'नींद (0)' की सिफारिश की गई थी। 'नींद (1)' वास्तव में एक नींद है। –

+11

नींद (0) केवल उपज होती है यदि उच्च प्राथमिकता के साथ चलाने के लिए कोई अन्य धागा तैयार होता है। यहां इरादा नहीं है। –

+0

केवल समान प्राथमिकता के धागे वास्तव में ... जो आम तौर पर उपज का मतलब है। –

5

मैंने स्रोत नहीं पढ़ा है, लेकिन यह एक लॉकलेस समरूपता की तरह दिखता है। आप हैशटेबल से पढ़ने की कोशिश कर रहे हैं, लेकिन कोई और इसे लिख रहा है, इसलिए आप isWriterInProgress अनसेट होने तक प्रतीक्षा करें और आपके द्वारा पढ़े गए संस्करण में कोई बदलाव नहीं आया है।

यह समझा नहीं गया क्यों उदा। हम हमेशा कम से कम एक बार इंतजार करते हैं। संपादित करें: ऐसा इसलिए है क्योंकि हम नहीं करते हैं, धन्यवाद @ मैसीज ने इसे इंगित करने के लिए। जब कोई विवाद नहीं होता है तो हम तुरंत आगे बढ़ते हैं। मुझे नहीं पता कि क्यों 8 जादू के बजाय जादू संख्या है 4 या 16, यद्यपि।

+3

नहीं हम नहीं करते हैं। '++ num3' के बाद, 'num3' 1 होगा। या मुझे गंभीर रूप से कैफीन की कमी है। –

+0

@MaciejStachowski ओह, अच्छा पकड़, मैं इसे गलत तरीके से पढ़ता हूं। –

+0

नींद केवल 8 निरंतर पुनरावृत्तियों के बाद की जाती है जिसमें एक लेखक प्रगति पर है या संस्करण गलत है। संभवतः, लेखक धागे को अपना काम करने का मौका देना। – dan04

7

शेष कार्यान्वयन कोड तक पहुंच के बिना, मैं केवल आपके द्वारा पोस्ट किए गए कार्यों के आधार पर एक शिक्षित अनुमान लगा सकता हूं।

ऐसा कहा जाता है, ऐसा लगता है कि यह हैशटेबल में कुछ या तो मेमोरी या डिस्क में अपडेट करने की कोशिश कर रहा है, और इसे समाप्त करने के लिए प्रतीक्षा करते समय एक अनंत लूप कर रहा है (जैसा कि isWriterInProgress की जांच करके देखा गया है)।

यदि यह एकल-कोर प्रोसेसर है, तो यह केवल एक ही समय में एक थ्रेड चला सकता है। इस तरह के निरंतर लूप में जाकर आसानी से अन्य धागे को चलाने का मौका नहीं मिल सकता है, लेकिन Thread.Sleep(1) प्रोसेसर को लेखक को समय देने का मौका देता है। प्रतीक्षा के बिना, लेखक धागे को कभी भी दौड़ने का मौका नहीं मिल सकता है, और कभी पूरा नहीं होता है।

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