2012-01-28 15 views
29

मेरे पास की साझा ऑब्जेक्ट पर एक साथ कई धागे push_back() पर कॉल कर रहे हैं। std::vector धागा सुरक्षित है? या क्या मुझे इसे थ्रेड सुरक्षित बनाने के लिए तंत्र को लागू करने की आवश्यकता है?
मैं अतिरिक्त "लॉकिंग और फ्रीिंग" काम करने से बचना चाहता हूं क्योंकि मैं लाइब्रेरी डिज़ाइनर की बजाय लाइब्रेरी उपयोगकर्ता हूं। मुझे वेक्टर के लिए मौजूदा थ्रेड-सुरक्षित समाधान देखने की उम्मीद है। boost::vector के बारे में, जिसे नव 1.48.0 आगे से बढ़ावा दिया गया था। क्या यह धागा सुरक्षित है?क्या std :: vector या boost :: वेक्टर थ्रेड सुरक्षित है?

+0

यह एक डुप्लिकेट होना चाहिए। लेकिन, नहीं, मानक कंटेनरों में से कोई भी थ्रेड-सुरक्षित नहीं है। – smparkes

+0

यह भी देखें: http://stackoverflow.com/questions/1999122/how-to-define-threadsafe – ergosys

+0

काफी डुप्ली नहीं है, लेकिन संबंधित: http://stackoverflow.com/questions/1099513/threadsafe-vector-class- for-c – ergosys

उत्तर

44

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

  1. वहाँ एक ही कंटेनर के कई समवर्ती पाठकों हो सकता है
  2. अगर एक लेखक है, वहाँ कोई और अधिक लेखकों और कोई पाठकों होगा

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

उपर्युक्त गारंटी देने वाली आवश्यकताओं को पूरा करने के लिए आपको संभवतः समेकित रूप से एक्सेस किए गए कंटेनर के लिए बाहरी लॉकिंग के कुछ रूपों का उपयोग करना होगा। मुझे बूस्ट कंटेनर के बारे में पता नहीं है, लेकिन यदि उनके पास मानक कंटेनर के समान इंटरफेस है तो मुझे संदेह होगा कि उनके पास बिल्कुल वही गारंटी है।

की गारंटी देता है और आवश्यकताओं 17.6.4.10 में दिए गए हैं [res.on.objects] अनुच्छेद 1:

एक कार्यक्रम के व्यवहार अपरिभाषित है अलग धागे से मानक पुस्तकालय कार्यों के लिए कॉल एक डेटा परिचय हो सकता है यदि दौड़। जिन शर्तों के तहत यह हो सकता है वे 17.6.5.9 में निर्दिष्ट हैं। [नोट: थ्रेड के बीच साझा किए गए मानक लाइब्रेरी प्रकार की ऑब्जेक्ट को संशोधित करना अनिर्धारित व्यवहार को जोखिम देता है जब तक कि उस प्रकार की ऑब्जेक्ट्स स्पष्ट रूप से डेटा रेस के बिना तेज़ होने के रूप में निर्दिष्ट नहीं होती हैं या उपयोगकर्ता लॉकिंग तंत्र की आपूर्ति करता है। -endnote]

... और 17.6.5.9 [res.on.data.races]। यह खंड अनिवार्य रूप से अधिक अनौपचारिक वर्णन का विवरण नहीं देता है।

+0

जिसे पुनर्वितरण कहा जाता है :) – vines

+2

यह [पुन: प्रशिक्षित] (http://en.wikipedia.org/wiki/Reentrancy_%28computing%29) अगर यह केवल कार्य करता था। हालांकि, ऐसी वस्तुएं शामिल हैं जिन्हें पढ़ने की प्रक्रिया द्वारा संशोधित नहीं किया जाना चाहिए। इसके अलावा, पुनर्वितरण एकल धागे वाले कार्यक्रमों में रिकर्सिव कॉल करने योग्य होने की सुविधा को संदर्भित करता है। –

+0

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

25

मेरे पास std :: vector के साझा ऑब्जेक्ट पर push_back() को एक साथ कई थ्रेड हैं। क्या std :: वेक्टर थ्रेड सुरक्षित है?

यह असुरक्षित है।

या क्या मुझे इसे थ्रेड सुरक्षित बनाने के लिए तंत्र को लागू करने की आवश्यकता है?

हां।

मैं अतिरिक्त "लॉकिंग और फ्रीिंग" काम करने से बचना चाहता हूं क्योंकि मैं पुस्तकालय डिजाइनर की बजाय लाइब्रेरी उपयोगकर्ता हूं। मुझे वेक्टर के लिए मौजूदा थ्रेड-सुरक्षित समाधान देखने की उम्मीद है।

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

बूस्ट :: वेक्टर के बारे में कैसे, जिसे नया 1.48.0 आगे बढ़ने से पेश किया गया था। क्या यह धागा सुरक्षित है?

डॉक्स राज्य:

//! boost::container::vector is similar to std::vector but it's compatible 
//! with shared memory and memory mapped files. 
8

मैं एक से अधिक थ्रेड एक साथ बुला push_back() std :: वेक्टर का एक साझा वस्तु पर है। ... मुझे वेक्टर के लिए मौजूदा थ्रेड-सुरक्षित समाधान देखने की उम्मीद है।

Intel's TBB में concurrent_vector पर एक नज़र डालें। कड़ाई से बोलते हुए, यह आंतरिक रूप से std::vector से काफी अलग है और एपीआई द्वारा पूरी तरह से संगत नहीं है, लेकिन फिर भी उपयुक्त हो सकता है। आपको इसके डिजाइन और कार्यक्षमता in the blogs of TBB developers के कुछ विवरण मिल सकते हैं।

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