सबसे खराब (वास्तव में काम नहीं करेगा)
की पहुँच संशोधक बदलें counter
करने के लिएpublic volatile
जैसा कि अन्य लोगों ने उल्लेख किया है, यह अपने आप में वास्तव में बिल्कुल भी सुरक्षित नहीं है। मुद्दा volatile
यह है कि कई सीपीयू पर चलने वाले कई धागे डेटा और री-ऑर्डर निर्देशों को कैश और कर सकते हैं।
यदि यह नहीं है volatile
, और सीपीयू ए मूल्य बढ़ाता है, तो सीपीयू बी वास्तव में कुछ समय बाद तक उस बढ़े हुए मूल्य को नहीं देख सकता है, जिससे समस्या हो सकती है।
यदि ऐसा है volatile
, तो यह सुनिश्चित करता है कि दो सीपीयू एक ही समय में एक ही डेटा देखें। यह उन सभी को उनके रीड्स को इंटरलेय करने से रोकता नहीं है और उन ऑपरेशनों को लिखता है जो समस्या है जिससे आप बचने की कोशिश कर रहे हैं।
दूसरा सबसे अच्छा:
lock(this.locker) this.counter++
;
यह करने के लिए सुरक्षित है (बशर्ते आप lock
हर जगह जिसे आप एक्सेस करते हैं उसे याद रखें this.counter
)। यह किसी भी अन्य धागे को किसी अन्य कोड को निष्पादित करने से रोकता है जो इसके द्वारा संरक्षित है locker
। ताले का उपयोग करना, ऊपर के रूप में मल्टी-सीपीयू रीऑर्डरिंग समस्याओं को रोकता है, जो बहुत अच्छा है।
समस्या यह है कि, लॉकिंग धीमा है, और यदि आप locker
किसी अन्य स्थान पर फिर से उपयोग करते हैं जो वास्तव में संबंधित नहीं है, तो आप बिना किसी कारण के अपने अन्य थ्रेड्स को अवरुद्ध कर सकते हैं।
श्रेष्ठ
Interlocked.Increment(ref this.counter);
यह सुरक्षित है, क्योंकि यह प्रभावी रूप से रीड, इंक्रीमेंट और 'एक हिट' में लिखता है, जिसे बाधित नहीं किया जा सकता है। इस वजह से, यह किसी अन्य कोड को प्रभावित नहीं करेगा, और आपको कहीं और लॉक करने के लिए याद रखने की आवश्यकता नहीं है। यह बहुत तेज़ है (जैसा कि MSDN कहता है, आधुनिक CPU पर, यह अक्सर शाब्दिक रूप से एक एकल CPU निर्देश है)।
मुझे पूरी तरह से यकीन नहीं है, लेकिन अगर यह अन्य सीपीयू को पुनः व्यवस्थित करने वाली चीजों के आसपास हो जाता है, या यदि आपको वेतन वृद्धि के साथ अस्थिरता को भी संयोजित करने की आवश्यकता है।
InterlockedNotes:
- इंटरलेक्ट किए गए तरीके कॉरपोरेट या सीपीयू के किसी भी नंबर पर सुरक्षित रूप से सुरक्षित हैं।
- इंटरलॉक की गई विधियाँ उनके द्वारा निष्पादित किए जाने वाले निर्देशों के चारों ओर एक पूर्ण बाड़ लगाती हैं, इसलिए पुनरावृत्ति नहीं होती है।
- इंटरलॉक्ड तरीकों की जरूरत नहीं है या यहां तक कि एक अस्थिर क्षेत्र तक पहुंच का समर्थन नहीं करते हैं , क्योंकि अस्थिर को दिए गए क्षेत्र पर संचालन के चारों ओर एक आधा बाड़ रखा जाता है और इंटरलॉक किया गया पूर्ण बाड़ का उपयोग कर रहा है।
फुटनोट: वाष्पशील वास्तव में किसके लिए अच्छा है।
जैसा कि volatile
इस प्रकार के बहुस्तरीय मुद्दों को रोकता नहीं है, इसके लिए क्या है? एक अच्छा उदाहरण कह रहा है कि आपके पास दो धागे हैं, एक जो हमेशा एक चर (लिख queueLength
) को लिखता है , और एक जो हमेशा उसी चर से पढ़ता है।
यदि queueLength
अस्थिर नहीं है, तो थ्रेड A पांच बार लिख सकता है, लेकिन थ्रेड बी उन राइट्स को विलंबित (या गलत तरीके से भी संभावित) के रूप में देख सकता है।
एक समाधान लॉक करना होगा, लेकिन आप इस स्थिति में अस्थिरता का भी उपयोग कर सकते हैं। यह सुनिश्चित करेगा कि थ्रेड बी में हमेशा सबसे ऊपर की चीज दिखाई देगी जो थ्रेड ए ने लिखी है। ध्यान दें कि यह तर्क केवल तभी काम करता है जब आपके पास ऐसे लेखक हों जो कभी नहीं पढ़ते हैं, और जो पाठक कभी नहीं लिखते हैं, और यदि आप जो चीज लिख रहे हैं वह एक परमाणु मूल्य है। जैसे ही आप एक एकल रीड-संशोधित-लेखन करते हैं, आपको इंटरलॉक किए गए संचालन पर जाने या लॉक का उपयोग करने की आवश्यकता होती है।