2009-07-27 17 views
60

मेरे पास एक वेरिएबल है जिसका उपयोग मैं राज्य का प्रतिनिधित्व करने के लिए कर रहा हूं। इसे कई धागे से पढ़ और लिखा जा सकता है।इंटरलाक्ड और अस्थिर

मैं इसे बदलने के लिए Interlocked.Exchange और Interlocked.CompareExchange का उपयोग कर रहा हूं। हालांकि मैं इसे कई धागे से पढ़ रहा हूं।

मुझे पता है कि volatile का उपयोग यह सुनिश्चित करने के लिए किया जा सकता है कि चर स्थानीय रूप से कैश नहीं किया गया है लेकिन हमेशा स्मृति से सीधे पढ़ता है।

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

मैं यह सुनिश्चित करना चाहता हूं कि प्रत्येक थ्रेड चर के नवीनतम मूल्य को पढ़ रहा है और कुछ कैश्ड संस्करण नहीं है, लेकिन मैं अस्थिरता का उपयोग नहीं कर सकता।

Interlocked.Read है लेकिन यह 64 बिट प्रकारों के लिए है और कॉम्पैक्ट फ्रेमवर्क पर उपलब्ध नहीं है। इसके लिए प्रलेखन कहता है कि 32 बिट प्रकारों के लिए इसकी आवश्यकता नहीं है क्योंकि वे पहले से ही एक ही ऑपरेशन में प्रदर्शन कर चुके हैं।

इंटरनेट पर किए गए बयान हैं कि यदि आप अपनी सभी पहुंच के लिए इंटरलाक्ड विधियों का उपयोग कर रहे हैं तो आपको अस्थिरता की आवश्यकता नहीं है। हालांकि आप इंटरलॉक विधियों का उपयोग करके 32 बिट वैरिएबल नहीं पढ़ सकते हैं, इसलिए आपकी सभी एक्सेस के लिए इंटरलॉक विधियों का उपयोग करने का कोई तरीका नहीं है।

क्या थ्रेड सुरक्षित पढ़ने और लॉक का उपयोग किए बिना मेरे चर के लिखने का कोई तरीका है?

+2

वास्तव में अच्छा सवाल है। एक नियमित ताला का उपयोग करना एक * महत्वपूर्ण निष्पादन बिंदु * का तात्पर्य है और गारंटी देता है कि आपका मान सभी धागे के लिए अद्यतित होगा। हालांकि, इंटरलाक्ड। एक्सचेंज 'लॉक' का उपयोग करके लागू नहीं किया गया है और मुझे कोई संदर्भ नहीं मिल रहा है कि यह ऐसी गारंटी देता है। – Thorarin

उत्तर

30

जब आप Interlocked.Xxx फ़ंक्शंस का उपयोग कर रहे हैं तो आप उस चेतावनी को सुरक्षित रूप से अवहेलना कर सकते हैं (this question देखें), क्योंकि वे हमेशा अस्थिर संचालन करते हैं। तो volatile चर साझा राज्य के लिए बिल्कुल ठीक है। यदि आप हर कीमत पर चेतावनी से छुटकारा पाने के लिए चाहते हैं, तो आप वास्तव में Interlocked.CompareExchange (ref counter, 0, 0) के साथ एक इंटरलॉक रीड कर सकते हैं।

संपादित करें: वास्तव में, यदि आप अपने राज्य चर केवल पर volatile जरूरत है अगर आप सीधे इसे करने के लिए लिखने के लिए जा रहे हैं (अर्थात Interlocked.Xxx का उपयोग नहीं)। As jerryjvl mentioned, एक इंटरलॉक (या अस्थिर) ऑपरेशन के साथ अद्यतन एक चर के पढ़ने का सबसे हालिया मूल्य उपयोग करेगा।

+0

जहां मुझे 0 को उस मान के साथ बदलना चाहिए जहां मेरा चर कभी नहीं होगा? – trampster

+3

पुhew, अगर ऐसा नहीं होता है, तो इंटरलाक्ड बहुत बेकार होगा। मुझे एक मिनट के लिए डर दिया :) – Thorarin

+0

@ डैनियल: नहीं, स्थिरता कोई फर्क नहीं पड़ता, क्योंकि 'तुलना एक्सचेंज' '0' के साथ' 0' के साथ बदल दिया जाएगा यदि काउंटर '0' है - यानी नो-ऑप। –

31

इंटरलाक्ड ऑपरेशंस और अस्थिरता वास्तव में एक ही समय में उपयोग नहीं की जानी चाहिए। आपको चेतावनी मिलने का कारण यह है क्योंकि यह (लगभग?) हमेशा इंगित करता है कि आपने जो किया है उसे गलत समझा है।

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

जब कोई फ़ील्ड अस्थिर चिह्नित नहीं होता है, तो आप समान गारंटी देने के लिए Interlocked संचालन का उपयोग कर सकते हैं, क्योंकि यह कैश को फ़्लश करने का कारण बनता है ताकि अद्यतन अन्य सभी प्रोसेसर के लिए दृश्यमान हो ... यह लाभ है आप पढ़ने के बजाए अद्यतन पर ओवरहेड डालते हैं।

इनमें से कौन सा दृष्टिकोण सबसे अच्छा प्रदर्शन करता है इस पर निर्भर करता है कि आप वास्तव में क्या कर रहे हैं। और यह स्पष्टीकरण एक सकल अति-सरलीकरण है।लेकिन यह इस से स्पष्ट होना चाहिए कि एक ही समय में दोनों करना व्यर्थ है।

+0

ठीक है तो अगर मैं केवल लिखने के लिए इंटरलाक्ड का उपयोग कर रहा हूं तो मानक पढ़ना हमेशा अद्यतित होगा? – trampster

+0

आम तौर पर नौकरी करना चाहिए, हां ... यही कारण है कि (लंबे/उलझन के अलावा) मूल्यों को पढ़ने के लिए इंटरलाक्ड ऑपरेशंस नहीं हैं। – jerryjvl

+2

अस्थिरता और इंटरलाक्ड का उपयोग करने के साथ स्वाभाविक रूप से गलत कुछ भी नहीं है। आपको चेतावनी मिलने का कारण यह है कि 'अस्थिर' यह है कि 'अस्थिर' प्रकार प्रणाली का हिस्सा नहीं है, और संदर्भ प्राप्त करने वाले कैली को यह नहीं पता होगा कि संदर्भित चर को अस्थिर पहुंच की आवश्यकता है। –

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