दिलचस्प पोस्ट
इवेंट हैंडलर स्मृति लीक से बचने के लिए क्यों और कैसे? मोबाइल डिवाइस का पता लगाने का सबसे सरल तरीका सी # में विधि हस्ताक्षर वेबकिट सीएसएस एनीमेशन समस्या – एनीमेशन के अंत की स्थिति को कायम करते हैं? क्रॉस-ब्राउज़र XmlHttpRequest को पुनः प्राप्त करने का सबसे आसान तरीका टीएसक्यूएल ईमेल सत्यापन (रेगेक्स के बिना) रैगेक्स के साथ एक स्ट्रिंग में कोई संख्या बढ़ाएं PHP द्वारा वेबपेज के ओपन ग्राफ़ प्रोटोकॉल कैसे प्राप्त करें? वेबपेज पर कस्टम राइट-क्लिक मेनू कैसे जोड़ें? एचटीएमएल को एक छवि के रूप में प्रस्तुत करना सॉकेट '/var/mysql/mysql.sock' के माध्यम से स्थानीय MySQL सर्वर से कनेक्ट नहीं किया जा सकता है (38) फैक्टरी डिज़ाइन पैटर्न को कार्यान्वित करते समय 'इंस्टॉलेशनफ' से कैसे बचें? कैसे स्वयं को अस्वास्थ्ययोग्य पॉइंटर <Void> प्रकार में तेजी से डाली जाए @ManyToMany हाइबरनेट अतिरिक्त तालिका में अतिरिक्त क्षेत्र (एस) जोड़ सकते हैं? jQuery का चयन करें और टेक्स्टनोड लपेटें

क्या सी ++ 11 में त्रि-सुरक्षित धागा सुरक्षित है?

मैंने सुना है कि const मतलब है धागा-सुरक्षित C ++ 11 में क्या यह सच है?

क्या इसका मतलब const अब जावा के synchronized के बराबर है?

क्या वे कीवर्ड से बाहर चल रहे हैं?

Solutions Collecting From Web of "क्या सी ++ 11 में त्रि-सुरक्षित धागा सुरक्षित है?"

मैंने सुना है कि const मतलब है धागा-सुरक्षित C ++ 11 में क्या यह सच है?

यह कुछ हद तक सच है …

मानक भाषा को धागा-सुरक्षा पर यह कहना है:

[1.10 / 4] दो अभिव्यक्ति मूल्यांकन कार्य संघर्ष अगर उनमें से एक मेमोरी स्थान (1.7) को संशोधित करता है और दूसरे एक ही मेमोरी स्थान को एक्सेस या संशोधित करता है।

[1.10 / 21] एक प्रोग्राम के निष्पादन में डेटा दौड़ शामिल है, अगर इसमें अलग-अलग धागे में दो विवादित क्रियाएं हैं, जिनमें से कम से कम एक परमाणु नहीं है, और न ही दूसरे से पहले होता है अनिर्धारित व्यवहार में ऐसा कोई भी डेटा रेस परिणाम।

जो एक डेटा दौड़ होने की पर्याप्त स्थिति के अलावा कुछ भी नहीं है:

  1. किसी वस्तु पर एक ही समय में दो या दो से अधिक क्रियाएं होती हैं; तथा
  2. उनमें से कम से कम एक लिखना है।

मानक पुस्तकालय उस पर बनाता है, थोड़ा आगे जा रहा है:

[17.6.5.9/1] यह खंड उन आवश्यकताओं को निर्दिष्ट करता है जो डेटा दौड़ (1.10) को रोकने के लिए कार्यान्वयन करेगा। प्रत्येक मानक पुस्तकालय फ़ंक्शन प्रत्येक आवश्यकता को पूरा करेगा जब तक अन्यथा निर्दिष्ट नहीं किया गया हो। कार्यान्वयन नीचे दिए गए विशेषताओं के अलावा अन्य मामलों में डेटा दौड़ को रोक सकता है।

[17.6.5.9/3] सी ++ मानक पुस्तकालय फ़ंक्शन प्रत्यक्ष या अप्रत्यक्ष रूप से वर्तमान धागा के अलावा अन्य थ्रेड्स से सुलभ ऑब्जेक्ट (1.10) को संशोधित नहीं करेगा जब तक कि ऑब्जेक्ट फ़ंक्शन के गैर-

जो सरल शब्दों में कहता है कि उसे const const होने के लिए const ऑब्जेक्ट्स पर आपरेशन की उम्मीद है इसका मतलब यह है कि मानक लाइब्रेरी किसी भी प्रकार की ऑब्जेक्ट्स पर आपरेशन के रूप में लंबे समय तक डाटा दौड़ शुरू नहीं करेंगे

  1. पूरी तरह से पढ़ता है – यह है, कोई लिखता नहीं है -; या
  2. आंतरिक लेखन को सिंक्रनाइज़ करता है

यदि यह उम्मीद आपके किसी प्रकार के लिए नहीं रखती है, तो सीधे मानक या अप्रत्यक्ष रूप से स्टैण्डर्ड लाइब्रेरी के किसी भी घटक के साथ इसका इस्तेमाल करके डेटा रेस में परिणाम हो सकता है। निष्कर्ष में, const का मतलब मानक लाइब्रेरी बिंदु से धागा-सुरक्षित है। यह ध्यान रखना महत्वपूर्ण है कि यह केवल एक अनुबंध है और इसे कंपाइलर द्वारा लागू नहीं किया जाएगा, यदि आप इसे तोड़ते हैं तो आप अपरिभाषित व्यवहार प्राप्त करते हैं और आप स्वयं ही होते हैं चाहे const मौजूद है या नहीं कोड पीढ़ी को प्रभावित नहीं करेगा – डेटा दौड़ के संबंध में कम से कम नहीं -।

क्या इसका मतलब const अब जावा के synchronized के बराबर है?

नहीं हर्गिज नहीं…

आयत का प्रतिनिधित्व करते हुए निम्नलिखित अति सरलीकृत वर्ग पर विचार करें:

 class rect { int width = 0, height = 0; public: /*...*/ void set_size( int new_width, int new_height ) { width = new_width; height = new_height; } int area() const { return width * height; } }; 

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

ध्यान दें कि इसका मतलब यह नहीं है कि rect थ्रेड-सुरक्षित है । वास्तव में, यह देखने में आसान है कि अगर एक कॉल area को एक ही समय में होना चाहिए, तो एक कॉल को एक निश्चित set_size पर set_size करना होगा, फिर area एक पुराने चौड़ाई और नई ऊँचाई (या यहां तक ​​कि इसके आधार पर इसके परिणाम की गणना कर सकता है विकृत मूल्यों पर)

लेकिन यह ठीक है, rect const नहीं है, इसलिए यह सब के बाद धागा-सुरक्षित होने की भी उम्मीद नहीं है। दूसरी तरफ, एक वस्तु को घोषित किया गया है कि कोई भी const_cast संभव नहीं है (और यदि आप const_cast पर विचार कर रहे हैं तो मूल रूप से घोषित const बारे में const_cast तो आपको अपरिभाषित-व्यवहार मिलता है और यही है)।

तो इसका मतलब क्या है?

मान लीजिए – तर्क के लिए- कि गुणाकरण कार्य अत्यंत महंगा है और संभव है कि हम उनसे बेहतर ढंग से बचें। हम उस क्षेत्र की गणना केवल तभी कर सकते हैं अगर यह अनुरोध किया गया हो, और फिर इसे भविष्य में फिर से अनुरोध किए जाने पर कैश करें:

 class rect { int width = 0, height = 0; mutable int cached_area = 0; mutable bool cached_area_valid = true; public: /*...*/ void set_size( int new_width, int new_height ) { cached_area_valid = ( width == new_width && height == new_height ); width = new_width; height = new_height; } int area() const { if( !cached_area_valid ) { cached_area = width; cached_area *= height; cached_area_valid = true; } return cached_area; } }; 

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

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

जैसे ही हम एक मानक कंटेनर में प्रत्यक्ष रूप से या अप्रत्यक्ष रूप से एक rect डालते हैं- हम मानक पुस्तकालय के साथ एक अनुबंध में प्रवेश कर रहे हैं। उस अनुबंध को सम्मानित करते हुए एक const समारोह में लिखते रहना, हमें उन लिखने की आंतरिक रूप से सिंक्रनाइज़ करने की आवश्यकता है:

 class rect { int width = 0, height = 0; mutable std::mutex cache_mutex; mutable int cached_area = 0; mutable bool cached_area_valid = true; public: /*...*/ void set_size( int new_width, int new_height ) { if( new_width != width || new_height != height ) { std::lock_guard< std::mutex > guard( cache_mutex ); cached_area_valid = false; } width = new_width; height = new_height; } int area() const { std::lock_guard< std::mutex > guard( cache_mutex ); if( !cached_area_valid ) { cached_area = width; cached_area *= height; cached_area_valid = true; } return cached_area; } }; 

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

अगर हम वास्तव में एक धागा सुरक्षित सुरक्षित करना चाहते थे, तो हम गैर-थ्रेड-सुरक्षित rect रक्षा के लिए एक सिंक्रनाइज़ेशन आदिम का उपयोग करेंगे।

क्या वे कीवर्ड से बाहर चल रहे हैं?

हाँ वे हैं। वे दिन के बाद से खोजशब्दों से बाहर चल रहे हैं


स्रोत : आप const एंड mutable नहीं mutable हर्ब सटर