यह सी # के लिए एक विस्तृत प्रश्न है।सी # थ्रेड सुरक्षा प्राप्त/सेट
मान लीजिए मैं एक वस्तु के साथ एक वर्ग मिल गया है, और कहा कि वस्तु एक ताला द्वारा सुरक्षित है:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
मैं एक मतदान धागा है कि संपत्ति क्वेरी करने के लिए सक्षम होना चाहते हैं। मैं भी थ्रेड को कभी-कभी उस ऑब्जेक्ट के गुणों को अपडेट करना चाहता हूं, और कभी-कभी उपयोगकर्ता उस प्रॉपर्टी को अपडेट कर सकता है, और उपयोगकर्ता उस संपत्ति को देखने में सक्षम होना चाहता है।
क्या निम्न कोड डेटा को ठीक से लॉक करेगा?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
तक 'ठीक से', मैं क्या मतलब है, अगर मैं
MyProperty.Field1 = 2;
या जो कुछ भी, क्षेत्र लॉक कर दिया जाएगा कॉल करने के लिए जब मैं अद्यतन करना चाहते हैं? क्या यह सेटिंग 'get' फ़ंक्शन के दायरे के अंदर बराबर ऑपरेटर द्वारा की जाती है, या 'get' फ़ंक्शन (और इसलिए लॉक) पहले खत्म हो जाएगी, और फिर सेटिंग, और फिर 'सेट' कहा जाता है, इस प्रकार बाईपासिंग ताला?
संपादित करें: चूंकि यह स्पष्ट रूप से चाल नहीं करेगा, क्या होगा? मैं की तरह कुछ करने की ज़रूरत है:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
कम या ज्यादा बस सुनिश्चित करें कि मैं केवल एक प्रति के लिए उपयोग किया है जो, जिसका अर्थ है कि अगर मैं के लिए गए थे दो धागे फोन एक ही समय में 'प्राप्त', वे प्रत्येक फ़ील्ड 1 (दाएं?) के समान मूल्य से शुरू करेंगे। क्या ऐसी संपत्ति पर लॉकिंग पढ़ने और लिखने का कोई तरीका है जो समझ में आता है? या क्या मुझे खुद को डेटा के बजाय कार्यों के अनुभागों को लॉक करने के लिए बाध्य होना चाहिए?
बस इतना उदाहरण यह है कि यह उदाहरण समझ में आता है: MyObject एक डिवाइस ड्राइवर है जो अतुल्यकालिक स्थिति देता है। मैं इसे एक धारावाहिक बंदरगाह के माध्यम से आदेश भेजता हूं, और फिर डिवाइस उन आदेशों को अपने स्वयं के मीठे समय में प्रतिसाद देता है। अभी, मेरे पास एक धागा है जो इसे अपनी स्थिति के लिए मतदान करता है ("क्या आप अभी भी वहां हैं? क्या आप कमांड स्वीकार कर सकते हैं?"), एक थ्रेड जो सीरियल पोर्ट पर प्रतिक्रियाओं की प्रतीक्षा करता है ("बस स्टेटस स्ट्रिंग 2 मिला, सबकुछ ठीक है"), और फिर यूआई थ्रेड जो अन्य कमांडों में लेता है ("उपयोगकर्ता चाहता है कि आप यह काम करें।") और ड्राइवर से प्रतिक्रिया पोस्ट करता है ("मैंने अभी यह काम किया है, अब उसके साथ यूआई अपडेट करें")। यही कारण है कि मैं ऑब्जेक्ट के क्षेत्र की बजाय ऑब्जेक्ट को लॉक करना चाहता हूं; यह ताले, ए, और बी की एक बड़ी संख्या होगी, इस वर्ग के हर डिवाइस में एक ही व्यवहार नहीं है, केवल सामान्य व्यवहार है, इसलिए यदि मैं ताले को वैयक्तिकृत करता हूं तो मुझे कई अलग-अलग संवाद कोड करना होगा।
सहमत हुए। मैंने सिंगलटन प्रश्न http://stackoverflow.com/questions/7095/is-the-c-static-constructor-thread-safe/7105#7105 – Zooba
हाँ के जवाब में आप जो पूछ रहे हैं उसके लिए नमूना समाधान प्रदान किया है, मैं ' जैसा कि आपने वर्णन किया है, ऑब्जेक्ट लॉक करने के साथ शायद आप जायेंगे। धन्यवाद। – mmr
अच्छा बिंदु, हालांकि अगर उसके पास 'पी' नामक कुछ 'माइप्रोपर्टी' थी और उसे दो थ्रेड कहा जाता था: 'p = new MyObject (12)' और 'p = new MyObject (5) 'तो * यह * एक्सेस सिंक्रनाइज़ हो जाएगी । हालांकि 'फ़ील्ड 1' सदस्य * कभी लॉक नहीं होगा। मुझे पूरा यकीन है कि आप यही कह रहे हैं, बस इसे अपने लिए समझने की कोशिश कर रहे हैं। – Snoopy