2008-12-12 20 views
9

कैसे करता const (संकेत, संदर्भ और सदस्य कार्यों) सी ++ में धागा सुरक्षा के साथ मदद?थ्रेड सुरक्षा और `const`

+0

ऐसा नहीं है। सिर्फ इसलिए कि एक चर का संदर्भ है, यह इंगित नहीं करता है कि उस चर के लिए कोई गैर संदर्भ नहीं है। –

+0

@ChrisBecke वैसे, यह http://stackoverflow.com/questions/14127379/does-const-mean-thread-safe-in-c11 एक बेहतर सवाल है, और अधिक मसा के साथ पूछा है। मुझे लगता है कि वहां दिए गए उत्तरों से पता चलता है कि एक ग्लिब 'यह नहीं है' पर्याप्त नहीं है। –

उत्तर

6

मुख्य समस्या एक से अधिक थ्रेड के साथ अस्थिरता है। कॉन्स इसे प्रतिबंधित करता है, लेकिन चूंकि आप कॉन्स्टेस को दूर कर सकते हैं, यह मूर्खतापूर्ण नहीं है।

+5

सच है, लेकिन आपको पैर में खुद को शूट करने के लिए अतिरिक्त कार्य करने की आवश्यकता है। –

+2

मैं सहमत हूं और इन दिनों सी # प्रोग्रामर के रूप में मुझे निश्चित रूप से याद आती है और –

+3

कोई कोड मूर्ख-प्रमाण नहीं है, लेकिन आपको मच्छी के खिलाफ नहीं, मर्फी के खिलाफ रक्षा करनी चाहिए। – Gorpik

14

कोई अपरिवर्तनीय (यानी, अपरिवर्तनीय) डेटा स्वाभाविक रूप से थ्रेड सुरक्षित है - एकाधिक धागे के लिए समान रूप से एक ही पढ़ने-पढ़ने वाले डेटा को पढ़ने के लिए कोई जोखिम नहीं है क्योंकि यह कभी नहीं बदला जा रहा है!

सी ++ में स्थिरांक के रूप में एक चर अंकन यह केवल पढ़ने के लिए और इस तरह सुरक्षित थ्रेड बनाता है।

+0

मान लीजिए कि आप कहीं भी म्यूटेबल का उपयोग नहीं कर रहे हैं ;-) –

+1

और यह मानते हुए कि यह प्रारंभिक है थ्रेड-सुरक्षित है। – xtofl

+1

प्रारंभिकरण आमतौर पर होता है। आप ऐसी ऑब्जेक्ट क्यों साझा करेंगे जिसे पूरी तरह से प्रारंभ नहीं किया गया है? –

6

एक स्थिरांक सदस्य समारोह राज्य में जो इसे सुरक्षित एक ही समय में एक से अधिक थ्रेड से कॉल करने के लिए बनाता है परिवर्तन नहीं होना चाहिए। हालांकि थ्रेड सुरक्षा कॉन्स का उद्देश्य नहीं है और सी ++ म्यूटेबल कीवर्ड और const_cast प्रदान करता है जिसका अर्थ है कि कॉन्स वास्तव में थ्रेड सुरक्षा की गारंटी नहीं देता है और इस उद्देश्य के लिए इस पर भरोसा नहीं किया जाना चाहिए।

4

कॉन्स्ट फ़ंक्शन थ्रेड सुरक्षित नहीं है। Normaly, आप अलग-अलग धागे से एक साथ कॉन्स ऑब्जेक्ट विधियों को कॉल कर सकते हैं, लेकिन यदि आप अलग-अलग धागे से नॉन कॉन्स्ट और कॉन्स्ट विधि को कॉल करते हैं तो आपको दौड़ की स्थिति मिलती है। इस जाँच करें:

class Foo 
{ 
    size_t size_; 
public: 
    ... 
    size_t get_size() const 
    { 
     return size_ 
    } 
}; 

class Bar 
{ 
    boost::shared_ptr<Foo> foo_; 
public: 
    //accessor 
    size_t get_size() const 
    { 
     size_t size = 0; 
     if (foo_) 
      size = foo_->size(); 
     return size; 
    } 
    //modifiers 
    void init() 
    { 
     foo_ = new Foo; 
    } 

    void clear() 
    { 
     foo_ = boost::shared_ptr<Foo>(); 
    } 
}; 

अगर किसी को कॉल init विधि, और फिर समवर्ती स्पष्ट फोन और तरीकों get_size, यह पहुँच उल्लंघन का कारण होगा। आपको पठन लेखन लॉक मुहावरे का उपयोग करना होगा। एक ही समय में एकाधिक एक्सेसर्स को बुलाया जा सकता है, और एक ही समय में केवल एक संशोधक को बुलाया जा सकता है। उदाहरण:

Foo myVar; 
const Foo* ptr1; 
Foo* ptr2; 

इस को देखते हुए, स्थिरांक के रूप में कोई गारंटी प्रदान करता है:

class Bar 
{ 
    boost::shared_ptr<Foo> foo_; 
    mutable tbb::spin_rw_mutex lock_; 
public: 
    //accessor 
    size_t get_size() const 
    { 
     size_t size = 0; 
     //lock modifiers 
     rw_mutex_type::scoped_lock lock(mutex, false); 
     if (foo_) 
      size = foo_->size(); 
     return size; 
    } 
    //modifiers 
    void init() 
    { 
     //lock accessor and modifiers 
     rw_mutex_type::scoped_lock lock(mutex, true); 
     foo_ = new Foo; 
    } 

    void clear() 
    { 
     //lock accessor and modifiers 
     rw_mutex_type::scoped_lock lock(mutex, true); 
     foo_ = boost::shared_ptr<Foo>(); 
    } 
}; 

TBB :: spin_rw_lock threading builing blocks library से एक म्युटेक्स वर्ग

+0

वास्तव में: स्थिरता केवल _helps_ धागा सुरक्षित अनुप्रयोगों का निर्माण – xtofl

4

सी ++ स्थिरांक की अनुमति देता है गैर स्थिरांक अलियासिंग जैसे है आपके डेटा की अपरिवर्तनीयता, भले ही आप इसे पाने के लिए कोई कास्टिंग या कुछ भी नहीं करते हैं। यदि आप ptr1 के माध्यम से myVar तक पहुंचते हैं, तो आप इसे ptr1 के माध्यम से नहीं बदल सकते (मान लीजिए कि मुझे सिंटैक्स सही मिला है, वह इरादा था।) हालांकि, यह अभी भी ptr2 के माध्यम से बदल सकता है। आप वास्तव में क्या चाहते हैं एक अलग अपरिवर्तनीय निर्माण है। यह सी ++ में मौजूद नहीं है।

3

कॉन्स्ट और धागा सुरक्षा ओर्थोगोनल अवधारणाओं रहे हैं।

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

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