2009-12-04 8 views
17

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

सब मैं कर रहा हूँ निम्नलिखित कोड का उपयोग कर नक्शा से पढ़ है:

std::string name; 
//here N is the field id for which I want the human readable name 
unsigned field_id = N; 
std::map<unsigned,std::string>::const_iterator map_it; 

// fields_p is a const std::map<unsigned, std::string>* to the map concerned. 
// multiple threads will share this. 
map_it = fields_p->find(field_id); 
if (map_it != fields_p->end()) 
{ 
    name = map_it->second; 
} 
else 
{ 
    name = ""; 
} 

क्या यह काम या वहाँ एक std :: एक से अधिक थ्रेड से नक्शा पढ़ने के साथ मुद्दों कर रहे हैं?

नोट: मैं वर्तमान में विजुअल स्टूडियो 2008 के साथ काम कर रहा हूं, लेकिन मैं इसे मुख्य मुख्य एसटीएल कार्यान्वयन के लिए एक्रोस काम करना चाहता हूं।

अद्यतन: कॉन्स्ट शुद्धता के लिए संपादित कोड नमूना।

उत्तर

16

यह तब तक कई धागे से काम करेगा जब तक आपका नक्शा वही रहता है। आपके द्वारा उपयोग किया जाने वाला मानचित्र अपरिवर्तनीय है, इसलिए कोई भी खोज वास्तव में उस मानचित्र में एक खोज करेगा जो बदलेगा नहीं। http://www.sgi.com/tech/stl/thread_safety.html

एसटीएल के एसजीआई कार्यान्वयन धागा सुरक्षित केवल अर्थ है कि अलग कंटेनरों को एक साथ पहुंच सुरक्षित हैं, और एक साथ पढ़ने में करने के लिए साझा करने के लिए पहुंचता है:

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

आप "साझा कंटेनरों के साथ-साथ पढ़ने के लिए एक्सेस" श्रेणी में आते हैं।

नोट: यह एसजीआई कार्यान्वयन के लिए सच है। आपको यह जांचना होगा कि क्या आप एक और कार्यान्वयन का उपयोग करते हैं। एक विकल्प के रूप में व्यापक रूप से उपयोग किए जाने वाले दो कार्यान्वयनों में से, एसटीएलपोर्ट ने मुझे पता है कि थ्रेड सुरक्षा में अंतर्निहित है। हालांकि मुझे अपाचे कार्यान्वयन के बारे में पता नहीं है।

+1

नोट: इस सवाल का जवाब एसजीआई एसटीएल implemenation तक सीमित है। ओपी ने उल्लेख नहीं किया कि किस का उपयोग किया जाता है। – foraidt

+0

सच है, मैं इस जानकारी को जोड़ने के लिए संपादित कर दूंगा। – laura

+0

मैं विजुअल स्टूडियो 2008 के साथ आने वाले कार्यान्वयन का उपयोग करता हूं, लेकिन मैं ऐसे उत्तर की तलाश में था जो सामान्य रूप से std :: मानचित्र को कवर करता है, या कम से कम अधिकांश कार्यान्वयन में यदि यह संभव हो तो। –

9

यह ठीक होना चाहिए। यदि आप केवल पढ़ने-योग्य व्यवहार को दस्तावेज़/लागू करना चाहते हैं तो आप const संदर्भों का उपयोग कर सकते हैं।

ध्यान दें कि शुद्धता की गारंटी नहीं है (सिद्धांत रूप में नक्शा find पर कॉल पर खुद को पुनर्व्यवस्थित करना चुन सकता है), भले ही आप केवल कॉन्स विधियों का उपयोग करें (वास्तव में प्रतिकूल कार्यान्वयन पेड़ को परिवर्तनीय घोषित कर सकता है)। हालांकि, यह अभ्यास में बहुत संभावना नहीं लगता है।

+0

मैं परिवर्तनीय गैर थ्रेड सुरक्षित आंतरिक बग़ी के साथ कार्यान्वयन पर विचार करूंगा। – hirschhornsalz

+0

मैंने मानचित्र के एक कॉन्स संदर्भ का उपयोग करने के लिए थोड़ा सा कोड अपडेट किया और एक const_iterator –

+0

drhirsch, एक गैर-थ्रेडसेफ कार्यान्वयन अभी भी मानक अनुरूप हो सकता है, लेकिन यह निश्चित रूप से खराब गुणवत्ता होगी। – Useless

3

हां यह है।

std :: सेट के बारे में एक ही सवाल के साथ संबंधित पोस्ट देखें:

Is the C++ std::set thread-safe?