2011-10-25 14 views
7

जावा से आ रहा है मैं उद्देश्य-सी में थ्रेड सुरक्षा सीखने की कोशिश कर रहा हूं। अब तक मैं झुक कर लिया है कि@ सिंक्रनाइज़, अस्थिर और OSMemoryBarrier() सभी का एक साथ उपयोग करना। क्या कोई दूसरा बताता है?

  • @synchronized ब्लॉक कोड का एक ही ब्लॉक करने के लिए समवर्ती पहुँच को रोकने
  • अस्थिर चर) धागे
  • OSMemoryBarrier करवाते परिवर्तन की दृश्यता (विश्वास दिलाता हूं; पहुंच

मेरा प्रश्न यह है कि: क्या उनमें से एक या अधिक में से एक का मतलब है? अगर मैं तीनों को चाहता हूं, तो क्या मुझे तीनों तकनीकों का उपयोग करने की ज़रूरत है?

उदाहरण: जब प्रवेश करने और एक तुल्यकालन ब्लॉक छोड़ने और पढ़ने या एक अस्थिर चर लेखन जब

volatile int first = 0; 
volatile int second = 0; 

[...] 

@synchronized { 
    OSMemoryBarrier(); 
    first++; 
    OSMemoryBarrier(); 
    second++; 
    OSMemoryBarrier(); 
} 

जावा तीनों में आश्वासन दिया जाता है। सच?

उत्तर

1

@synchronized निर्देश इस प्रकार परिवर्तित हो जाता है ...

- (NSString *)myString { 
    @synchronized(self) { 
    return [[myString retain] autorelease]; 
    } 
} 

हो जाता है ...

- (NSString *)myString { 
    NSString *retval = nil; 
    pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self); 
    pthread_mutex_lock(self_mutex); 
    retval = [[myString retain] autorelease]; 
    pthread_mutex_unlock(self_mutex); 
    return retval; 
} 
+0

तो सिंक्रनाइज़ ब्लॉक में प्रवेश करने और छोड़ने से स्मृति बाधाओं को पारित किया जाता है? और यदि एक चर के लिए एक सिंक्रनाइज़ ब्लॉक द्वारा संरक्षित किया जाता है, तो परिवर्तनीय को अस्थिर होने की आवश्यकता नहीं होती है, क्योंकि परिवर्तन हमेशा अन्य धागे के लिए दृश्यमान होते हैं? – Twilite

+0

मुझे इस प्रश्न के उत्तर में अस्थिरता पर अधिक जानकारी मिली: http://stackoverflow.com/questions/6866206/volatile-and-createthread ऐसा लगता है, अस्थिर स्मृति स्मृति बाधा उत्पन्न नहीं करता है और धागे के बीच पहुंच के सिंक्रनाइज़ेशन के लिए बेकार है। – Twilite

0

@synchronized से कोड का एक खंड की रक्षा नहीं करता फिर से प्रवेश किया जा रहा है - यह क्रियान्वित करने से बचाता है कोई कोड जो एक ही ऑब्जेक्ट के साथ @ सिंक्रनाइज़ का उपयोग करता है। तो अगर आप दो तरीकों

- (void)method1 { 
    @synchronized (self) { dothis(); } 
} 
- (void)method2 { 
    @synchronized (self) { dothat(); } 
} 

और दो अलग अलग सूत्र है, एक ही वस्तु के लिए Method1 और Method2 फोन तो dothis() और dothat() एक के बाद एक बुलाया जाएगा। बेशक यह भी सच है कि दो अलग-अलग थ्रेड एक ही ऑब्जेक्ट के लिए विधि 1 को कॉल करते हैं। @ सिंक्रनाइज़ेड आपको एक ही धागे पर एक ब्लॉक में प्रवेश करने से नहीं रोकता है, इसलिए उपरोक्त उदाहरण में() [self method2] कॉल कर सकता है और इसे अवरुद्ध नहीं किया जाएगा।

यदि आप अस्थिर या OSMemoryBarrier() का उपयोग कर रहे हैं तो मेरा सुझाव है कि आपका डिज़ाइन बहुत अधिक, बहुत जटिल है और आप जल्दी या बाद में परेशानी में भाग लेंगे।

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