7

मैं बहस कर रहा हूं कि बहु-थ्रेडेड एक्सेसर्स के लिए जीसीडी-आधारित पैटर्न में जाना है या नहीं। मैं वर्षों से एक्सेसर्स में कस्टम लॉक-आधारित सिंक्रनाइज़ेशन का उपयोग कर रहा हूं, लेकिन मुझे कुछ जानकारी मिली है (Intro to GCD) और ऐसा लगता है कि जीसीडी-आधारित दृष्टिकोण के पेशेवर हैं। मैं अपने आप को और दूसरों को निर्णय लेने के लिए यहां एक संवाद शुरू करने की उम्मीद कर रहा हूं।मल्टी-थ्रेडेड ऑब्जेक्टिव-सी एक्सेसर्स: जीसीडी बनाम ताले

- (id)something 
{ 
    __block id localSomething; 
    dispatch_sync(queue, ^{ 
     localSomething = [something retain]; 
    }); 
    return [localSomething autorelease]; 
} 

- (void)setSomething:(id)newSomething 
{ 
    dispatch_async(queue, ^{ 
     if(newSomething != something) 
     { 
      [something release]; 
      something = [newSomething retain]; 
      [self updateSomethingCaches]; 
     } 
    }); 
} 

समर्थक तरफ: आप संभवतः, का लाभ मिलेगा, लेखन पहुँच गैर अवरुद्ध;

पैटर्न की तरह दिखता है ताले से अधिक ऊपरी ऊपरी (शायद?); महत्वपूर्ण कोड खंडों से लौटने से पहले अनलॉक करने से भूलने से सुरक्षा; दूसरों?

विपक्ष: अपवाद हैंडलिंग मौजूद नहीं है इसलिए आपको इसे हर ब्लॉक में कोड करना होगा जिसमें आपको इसकी आवश्यकता हो सकती है।

क्या यह पैटर्न संभावित रूप से बहुप्रचारित एक्सेसर्स लिखने की अनुशंसित विधि है?

क्या इस उद्देश्य के लिए प्रेषण कतार बनाने के लिए मानक दृष्टिकोण हैं? दूसरे शब्दों में, ग्रैन्युलरिटी के व्यापार के लिए सर्वोत्तम प्रथाएं? ताले के साथ, उदाहरण के लिए, प्रत्येक विशेषता पर लॉकिंग पूरे ऑब्जेक्ट पर लॉक करने से अधिक बढ़िया अनाज है। प्रेषण कतारों के साथ, मैं कल्पना कर सकता हूं कि सभी वस्तुओं के लिए एक कतार का निर्माण प्रदर्शन बाधा उत्पन्न करेगा, इसलिए प्रति-वस्तु कतार उपयुक्त हैं? जाहिर है, उत्तर विशिष्ट अनुप्रयोग पर अत्यधिक निर्भर है, लेकिन दृष्टिकोण की व्यवहार्यता को मापने में सहायता के लिए प्रदर्शन ट्रेडऑफ ज्ञात हैं।

किसी भी जानकारी/अंतर्दृष्टि की सराहना की जाएगी।

+0

बस डेटा बिंदु के रूप में, कतार और पाथ्रेड ताले समान 'वजन' (80 बाइट बनाम 64 बाइट्स, तुलनीय अधिग्रहण समय) के होते हैं, लेकिन स्पष्ट धागे के बजाय कतारों का उपयोग कर्नेल-साइड थ्रेड के लिए वायर्ड मेमोरी बचाता है (जब तक आप किसी भी प्रकार के पूल के माध्यम से अपने स्पष्ट थ्रेड जीवनकाल को ध्यान से प्रबंधित करें) –

उत्तर

8

क्या यह पैटर्न संभावित रूप से मल्टीथ्रेड किए गए एक्सेसर्स लिखने की अनुशंसित विधि है?

मुझे लगता है कि आपने लिखा है कि एक धारावाहिक कतार के साथ दिमाग में, लेकिन इसके लिए कोई कारण नहीं है। इस पर विचार करें:

dispatch_queue_t queue = dispatch_queue_create("com.example", DISPATCH_QUEUE_CONCURRENT); 

// same thing as your example 
- (NSString*)something { 
    __block NSString *localSomething; 
    dispatch_sync(queue, ^{ 
     localSomething = _something; 
    }); 
    return localSomething; 
} 

- (void)setSomething:(NSString*)something { 
    dispatch_barrier_async(queue, ^{ 
     _something = something; 
    }); 
} 

यह समवर्ती पढ़ता है, लेकिन जब लिखने हो रहा है संगामिति निष्क्रिय करने के लिए एक प्रेषण बाधा उपयोग करता है। जीसीडी का एक बड़ा फायदा यह है कि समवर्ती पढ़ने की बजाय पूरे ऑब्जेक्ट को लॉक करने की अनुमति देता है जैसे @property (atomic) करता है।

दोनों asyncs (dispatch_async, dispatch_barrier_async) क्लाइंट प्वाइंट व्यू से तेज़ हैं, लेकिन सिंक की तुलना में निष्पादित करने के लिए धीमे हैं क्योंकि उन्हें ब्लॉक की प्रतिलिपि बनाना है, और इस तरह के एक छोटे से कार्य को ब्लॉक करना, प्रतिलिपि बनाने में लगने वाला समय सार्थक हो जाता है। मैं क्लाइंट को तेजी से लौट रहा हूं, इसलिए मैं इसके साथ ठीक हूं।

+0

अवरोध वैश्विक कतारों पर कार्य नहीं करते हैं। आपको एक निजी समवर्ती कतार की आवश्यकता होगी। –

+0

ओह, सच है, यह दस्तावेज़ों पर है, मैं इसे ठीक कर दूंगा, धन्यवाद। – Jano

+0

ब्लॉक_copy() –

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