2013-02-25 102 views
14

std :: map में ऑब्जेक्ट का संदर्भ थ्रेड सुरक्षित है?std :: मानचित्र थ्रेड-सुरक्षा

std::map< std::string, Object > _objects; 

नक्शा कई धागे से बदला जा सकता है और इस का उपयोग सिंक्रनाइज़ है, लेकिन मूल्य के संदर्भ में (वस्तु &) सिर्फ 1 उदाहरण और धागे से सुलभ। ऑब्जेक्ट & के साथ लिखने का कार्य है सुरक्षित है यदि कोई अन्य थ्रेड मानचित्र में आइटम जोड़ देगा? क्या यह फिर से आवंटित होगा?

+4

http://stackoverflow.com/questions/6438086/iterator-invalidation- नियम – inf

+0

यह धागा सुरक्षित नहीं है, दो धागे से डालें और आप एक असंगत स्थिति में समाप्त हो सकते हैं। – paulm

+1

@paulm, "_map कई धागे से बदला जा सकता है और इस का उपयोग कर सकते synchronized_ है" –

उत्तर

14

सी ++ 11 मानक गारंटी देता है कि const कंटेनरों तक विधि पहुंच अलग-अलग धागे से सुरक्षित है (यानी, दोनों const विधियों का उपयोग करें)।

इसके अलावा, [container.requirements.dataraces] राज्यों

कार्यान्वयन जब उसी क्रम में विभिन्न तत्वों में निहित वस्तु, की सामग्री को vector<bool>

छोड़कर डेटा दौड़ से बचने के लिए आवश्यक हैं

दूसरे शब्दों में, vector<bool> को छोड़कर अलग-अलग सामग्री को संशोधित करना डेटा रेस नहीं है।

अब, यदि एक थ्रेड किसी अन्य थ्रेड द्वारा उपयोग किए गए इटरेटर को अमान्य करता है, तो स्पष्ट रूप से यह एक डेटा रेस (और अपरिभाषित व्यवहार में परिणाम) है। यदि एक थ्रेड गैर-const कंटेनर तक पहुंच करता है, और दूसरा const एक्सेस करता है, तो यह एक डेटा रेस (और अपरिभाषित व्यवहार) है। (नोट: मल्टीथ्रेडिंग के उद्देश्य के लिए कई कार्यों को "const" माना जाता है, जिसमें begin, end और अन्य फ़ंक्शंस (और विधियां) हैं जो गैर-const हैं क्योंकि वे गैर-const इटरेटर्स लौटते हैं। [] इस सेट में शामिल है छद्म सुरक्षा कारणों के लिए छद्म- const, map और unordered_set आदि को छोड़कर - 23.2.2।1)।

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

मानकों के संदर्भ के लिए, 17.6.5.9.5 कि मानक पुस्तकालय से कार्यों दूर नहीं चलेगा की गारंटी और पढ़ने/तत्वों बेकार में लिखने के लिए लगता है।

तो संक्षिप्त उत्तर: आप सुरक्षित हैं, जब तक कि अन्य थ्रेड map में उस विशेष प्रविष्टि से सीधे गड़बड़ नहीं करता है।

+0

अन्य थ्रेड से दूसरी कुंजी के साथ एक और मान [कंटेनर.रेक्वायरमेंट्स डैरेसेस]/3 देखें। यही कारण है कि यह सुनिश्चित करता है के रूप में [associative.reqmnts]/9 –

+0

आप कुछ वहाँ है एक अत्याचार पढ़ नहीं द्वारा कहा विशिष्ट तत्वों समवर्ती संशोधित किया जा सकता है, और जैसा कि आप कहते हैं कि तत्व अन्य धागे में नक्शे के लिए अद्यतन द्वारा संशोधित नहीं किया जाएगा,? तत्वों के समवर्ती उपयोग सुरक्षित है, 'कॉन्स्ट' सदस्यों का उपयोग सुरक्षित है, कुछ गैर-'सदस्य' सदस्य संदर्भ या इटरेटर्स को अमान्य नहीं करेंगे - लेकिन गैर-'const' सदस्य * पढ़ने * की गारंटी नहीं देते हैं (और इस प्रकार एक कारण बनते हैं तत्व लिखने के साथ डेटा रेस) कंटेनर पर निर्दोष संचालन करते समय? मुझे ऐसा करने के लिए कंटेनर का कोई कारण नहीं दिखता है, लेकिन मुझे 23.2.2 में कुछ भी दिखाई नहीं देता है जो इसे अस्वीकार करता है। – Yakk

+0

मुझे लगता है कि 17.6.5.9.2? – Yakk

6

मानचित्र में तत्व स्थिर हैं, वे तब तक स्थानांतरित नहीं होते हैं जब तक कि मानचित्र मानचित्र से मिटा नहीं जाता है। यदि किसी दिए गए ऑब्जेक्ट में केवल एक धागा लिख ​​रहा है, और मानचित्र में परिवर्तन सही ढंग से सिंक्रनाइज़ किए जाते हैं, तो मुझे विश्वास है कि यह सुरक्षित रहेगा। मुझे यकीन है कि यह अभ्यास में सुरक्षित है, और मुझे लगता है कि यह सिद्धांत में भी सुरक्षित है।

मानक गारंटी देता है कि अलग-अलग एलीमेंट

के होते हुए भी (17.6.5.9) में [container.requirements.dataraces], अलग धागे के द्वारा संशोधित किया जा सकता है, कार्यान्वयन डेटा दौड़ से बचने के लिए आवश्यक हैं जब की सामग्री vector<bool> को छोड़कर, समान अनुक्रम में विभिन्न तत्वों में निहित वस्तु, समवर्ती रूप से संशोधित की जाती है।

यह केवल तत्वों को संशोधित करने के दौरान तत्वों को संशोधित करने की अनुमति देता है, न कि तत्वों को संशोधित करते समय मानचित्र में नए तत्व डालने के लिए। std::vector जैसे कुछ कंटेनर के लिए, वेक्टर को संशोधित करने से तत्वों को फिर से स्थानांतरित करके उन्हें स्थानांतरित किया जा सकता है, लेकिन [associative.reqmts]/9 सुनिश्चित करता है कि std::map मौजूदा तत्वों को अमान्य नहीं करेगा।

के बाद से std::map का कोई भी सदस्य समारोह उसके तत्वों के दूसरे सदस्य (यानी mapped_type) मुझे लगता है कि [res.on.data.races] का उपयोग करने की आवश्यकता है/5 कहते हैं कोई अन्य बात यह है कि सदस्य जब करने के लिए राईट का उल्लंघन करेगा मानचित्र को संशोधित करना (पहेली के उस अंतिम भाग के लिए याक के लिए धन्यवाद)

+0

की बात याद किया मैं (और सिर्फ इस सूत्र में) thread1 में मूल्य के संदर्भ में रखने के लिए, लेकिन जोड़ने – deeptowncitizen