मैं लिनक्स पर चल रहे एक बहुप्रचारित प्रोग्राम (जी ++ 4.3 के साथ संकलित) विकसित कर रहा हूं और यदि आप थोड़ी देर के लिए खोज करते हैं तो आपको std :: string के बारे में बहुत डरावनी कहानियां मिलती हैं जो जीसीसी के साथ थ्रेड-सुरक्षित नहीं है। यह माना जाता है कि आंतरिक रूप से यह कॉपी-ऑन-राइट का उपयोग करता है जो हेल्ग्रिंड जैसे टूल के साथ कहर बरकरार रखता है।क्या gcc 4.3 के साथ std :: string thead-safe है?
मैंने एक छोटा प्रोग्राम बनाया है जो एक स्ट्रिंग को दूसरी स्ट्रिंग में कॉपी करता है और यदि आप दोनों तारों का निरीक्षण करते हैं तो वे दोनों एक ही आंतरिक _M_p पॉइंटर साझा करते हैं। जब एक स्ट्रिंग को संशोधित किया जाता है तो पॉइंटर बदल जाता है ताकि कॉपी-ऑन-राइट सामान ठीक काम कर रहा हो।
मैं क्या चिंतित हूं कि क्या होता है यदि मैं दो धागे के बीच एक स्ट्रिंग साझा करता हूं (उदाहरण के लिए इसे दो धागे के बीच थ्रेडसेफ डेटाक्यू में ऑब्जेक्ट के रूप में पास करना)। मैंने पहले से ही '-pthread' विकल्प के साथ संकलन करने का प्रयास किया है लेकिन ऐसा लगता है कि यह बहुत अंतर नहीं करता है। तो मेरे सवाल:
- वहाँ threadsafe होने के लिए std :: स्ट्रिंग के लिए मजबूर करने कोई तरीका है? अगर यह प्राप्त करने के लिए कॉपी-ऑन-राइट व्यवहार अक्षम किया गया तो मुझे कोई फर्क नहीं पड़ता।
- अन्य लोगों ने इसे कैसे हल किया है? या मैं पागल हो रहा हूँ?
मैं एक निश्चित जवाब खोजने के लिए तो मुझे आशा है कि आप लोग मेरी मदद कर सकते नहीं कर पा रहे
संपादित करें:
वाह, यह इस तरह के एक संक्षेप में जवाब की एक पूरी बहुत कुछ है पहर। धन्यवाद! जब मैं गाय को अक्षम करना चाहता हूं तो मैं निश्चित रूप से जैक के समाधान का उपयोग करूंगा। लेकिन अब मुख्य प्रश्न बन गया है: क्या मुझे वास्तव में गाय को अक्षम करना है? या गाय थ्रेड के लिए 'बुककीपिंग' सुरक्षित है? मैं वर्तमान में libstdC++ सूत्रों ब्राउज़ कर रहा हूँ, लेकिन यह है कि पिछले कुछ समय से लेने के लिए यह पता लगाने जा रहा है ...
संपादित 2
ठीक libstdC++ स्रोत कोड ब्राउज़ की हैं और मैं libstd में कुछ इस तरह लगता है ++ - v3 /include/bits/basic_string.h:
_CharT*
_M_refcopy() throw()
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
__gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
return _M_refdata();
} // XXX MT
तो वहाँ निश्चित रूप से संदर्भ काउंटर करने के लिए परमाणु परिवर्तन के बारे में कुछ निष्कर्ष 01 है ...
मैं विक्रेता के टिप्पणी को यहां जवाब के रूप में चिह्नित कर रहा हूं क्योंकि मुझे लगता है कि हम इस निष्कर्ष पर पहुंचे हैं कि यह क्षेत्र अभी भी अनसुलझा है। गाय व्यवहार को रोकने के लिए मैं जैक लॉयड के जवाब का सुझाव दूंगा। एक दिलचस्प चर्चा के लिए सभी को धन्यवाद!
+1 अच्छा सवाल! दुर्भाग्यवश, लोग सिर्फ "थ्रेडसेफ" पढ़ते हैं और सोचते हैं "नहीं!"। वे पूरे सवाल को बेहतर ढंग से पढ़ते हैं! :) – sellibitze
चूंकि std :: string टेम्पलेट std :: basic_string का एक उदाहरण है, इसलिए स्रोत कोड पर एक नज़र रखना संभव हो सकता है। थ्रेड-सुरक्षा चालू/बंद करने वाले किसी भी मैक्रो को देखने का प्रयास करें। –
वैसे, बहु-थ्रेडेड वातावरण में कॉपी-ऑन-राइट धीमा है, आपको * इसका उपयोग नहीं करना चाहिए, इसके लिए तैयार नहीं होना चाहिए। – GManNickG