2009-08-10 7 views
12

ठीक में थ्रेड-सुरक्षित स्थिर चर बनाने की आवश्यकता है, ठीक है, यह सवाल से थोड़ा अधिक जटिल है।मुझे सी # .Net

class A 
{ 
    static int needsToBeThreadSafe = 0; 

    public static void M1() 
    { 
    needsToBeThreadSafe = RandomNumber(); 
    } 

    public static void M2() 
    { 
    print(needsToBeThreadSafe); 
    } 
} 

अब मैं अपेक्षा करते हैं कि एम 1() और M2() के बीच कॉल 'needsToBeThreadSafe' रहता है सुरक्षित थ्रेड।

+1

मतलब है कि आप एम 1() और एम 2 के लिए कॉल चाहते हैं() परमाणु हो सकता है? – Bombe

+2

"थ्रेड थ्रेड सुरक्षित" से आपका क्या मतलब है? –

उत्तर

18

क्या आप के बारे में पूछने की कोशिश कर रहा हो सकता है [ThreadStatic] विशेषता है। आप प्रत्येक थ्रेड वर्ग A का उपयोग करता है needsToBeThreadSafe का अपना अलग महत्व हो करना चाहते हैं तो आप बस [ThreadStatic] विशेषता के साथ उस क्षेत्र को सजाने के लिए की जरूरत है।

अधिक जानकारी के लिए MSDN documentation for ThreadStaticAttribute देखें।

static int needsToBeThreadSafe = 0; 
static System.Threading.ReaderWriterLockSlim rwl = new System.Threading.ReaderWriterLockSlim(); 

public static void M1() 
{ 
    try 
    { 
     rwl.EnterWriteLock(); 
     needsToBeThreadSafe = RandomNumber(); 
    } 
    finally 
    { 
     rwl.ExitWriteLock(); 
    } 

} 

public static void M2() 
{ 
    try 
    { 
     rwl.EnterReadLock(); 
     print(needsToBeThreadSafe); 
    } 
    finally 
    { 
     rwl.ExitReadLock(); 
    } 
} 
+0

मुझे लगता है कि हर कोई भी सही था, लेकिन मेरी स्थिति के लिए यह पूरी तरह से काम करता है। – Storm

+5

ठीक है, लेकिन थ्रेडस्टैट थ्रेडसेफ से कुछ और है। –

+0

किसी भी तरह, मुझे अभी एहसास हुआ कि वह वास्तव में क्या है वह एक मूल्य है जो थ्रेड के बीच साझा नहीं किया जाता है। इसके अलावा, थ्रेडस्टैटिक ** ** थ्रेड-सुरक्षित है क्योंकि वास्तव में कोई भी दो धागे समान वैरिएबल तक नहीं पहुंचते हैं (भले ही ऐसा लगता है कि वे हैं)। – paracycle

4
class A 
{ 
    static int needsToBeThreadSafe = 0; 
    static object statObjLocker = new object(); 

    public static void M1() 
    { 
     lock(statObjLocker) 
     { 
      needsToBeThreadSafe = RandomNumber(); 
     } 
    } 

    public static void M2() 
    { 
     lock(statObjLocker) 
     { 
      print(needsToBeThreadSafe); 
     } 
    } 
} 
+0

statObjLocker * readonly * होना चाहिए, केवल सावधानी बरतनी चाहिए ... – ipavlu

8

आपके पास दो विकल्प: अपने प्रस्तुत कोड के लिए सबसे आसान दी volatile कीवर्ड है। needsToBeThreadSafe को static volatile int के रूप में घोषित करें और यह गारंटी देगा कि उस चर के संदर्भ में कोई भी थ्रेड "नवीनतम" प्रतिलिपि प्राप्त करेगा, और चर को आपके कोड में कैश नहीं किया जाएगा।

कहा जा रहा है, यदि आप अधिक आम तौर पर यह सुनिश्चित करें कि M1() और M2() निष्पादित "atomically" चाहते हैं (या एक दूसरे के लिए कम से कम विशेष रूप से), तो आप एक lock उपयोग करना चाहते हैं। साफ वाक्य रचना एक "लॉक ब्लॉक", इस तरह से है:

private static object locker = new Object(); 

//.. 

public static void M1() 
{ 
    lock(locker) 
    { 
     //..method body here 
    } 
} 

public static void M2() 
{ 
    lock(locker) 
    { 
     //..method body here 
    } 
} 

के रूप में जो दृष्टिकोण लेने के लिए, कि आप पर निर्भर है करने के लिए और कोड द्वारा निर्धारित किया जाना चाहिए। यदि आपको केवल यह सुनिश्चित करना है कि एक सदस्य असाइनमेंट सभी धागे के लिए प्रचारित हो जाता है और कैश नहीं किया जाता है, तो volatile कीवर्ड सरल है और यह काम ठीक होगा। यदि यह उससे परे है, तो आप lock के साथ जाना चाह सकते हैं।

+0

लॉकर * readonly * होना चाहिए, केवल सावधानी बरतनी चाहिए ... – ipavlu

2

ध्वनि जैसा आपको Volatile सदस्य की आवश्यकता है।

static volatile int needsToBeThreadSafe = 0; 
+0

यह 200 9 टिप्पणी थी, लेकिन आजकल अस्थिर से बचने के लिए सबसे अच्छा है, क्योंकि इसका दुष्प्रभाव है ... – ipavlu

2

तुम भी ReaderWriterLockSlim उपयोग कर सकते हैं, कि और अधिक कुशल कई पढ़ता है और कम लेखन के लिए है।

class A 
{ 
    static volatile int needsToBeThreadSafe = 0; 

} 

लेकिन अगर आप:

लेकिन एक और अधिक minimalist दृष्टिकोण वहां मौजूद है, अपने नमूना कोड केवल needsToBeThreadSafe और के बाद से int परमाणु है आप केवल अस्थिर का उपयोग कर संकलक द्वारा कैशिंग को रोकने के लिए की जरूरत का उपयोग कर एक बयान से पता चलता जरूरतों की आवश्यकता है कई बयानों पर 'थ्रेडसेफ' होने के लिए, लॉक का उपयोग करें, लॉक का उपयोग करें।

+0

RWL केवल पढ़ने के लिए * * किया जाना चाहिए, सिर्फ एहतियात ... – ipavlu

2

साथ मैं lock() का उपयोग कर जवाब के साथ सहमत हैं कि सबसे सुरक्षित तरीका है शुरू करने के लिए:

+0

2009 जवाब था, लेकिन आजकल, यह जवाब में उपयोग करने के लिए बेहतर होगा अस्थिर रूप में अस्थिर से ताला सुझाव दुष्प्रभाव, जो आसानी से मुद्दों बनाने के लिए करते हैं है ... – ipavlu

20

कैसे के बारे में: आप

public static void M1() 
{ 
    Interlocked.Exchange(ref needsToBeThreadSafe, RandomNumber()); 
} 

public static void M2() 
{ 
    print(Interlocked.Read(ref needsToBeThreadSafe)); 
} 
+0

मैं इसे प्यार करता हूं, सुरक्षित है और बहुत तेज़ है, शम इसे आधे दशक के बाद केवल 4 अपवॉट्स (मेरा शामिल) मिला! – ipavlu