2012-03-07 17 views
8

सी ++ 11 thread-safe initialization of static variables जैसी सुविधाओं के प्रदान करता है, और कहा कि यह प्रश्न पूछते हैं, उदाहरण के लिए कहूँगा का हवाला देते हुए:क्या कोई सी ++ 11 थ्रेड-सुरक्षा गारंटी सी ++ 11 के साथ संकलित/लिंक किए गए तृतीय-पक्ष थ्रेड पुस्तकालयों पर लागू होती है?

Logger& g_logger() { 
    static Logger lg; 
    return lg; 
} 

तो जाहिरा तौर पर यह सच की परवाह किए बिना कि क्या एक मॉड्यूल एक सी ++ 11 संकलक के साथ संकलित (?) थ्रेड हेडर शामिल थे, या अपने शरीर में किसी भी धागे पैदा किया। आपको गारंटी दी जाती है भले ही यह किसी अन्य मॉड्यूल के खिलाफ जुड़ा हुआ हो जो C++ 11 थ्रेड का उपयोग करता है और फ़ंक्शन कहलाता है।

लेकिन यदि आपका "अन्य मॉड्यूल" जो इस कोड में कॉल करता है तो सी ++ 11 धागे का उपयोग नहीं कर रहा था, लेकिन क्यूटी के QThread जैसे कुछ। क्या इस तरह की गारंटी देने के लिए सी ++ 11 की क्षमता के दायरे के बाहर स्थैतिक पर परमाणु प्रारंभिक है? या सी ++ 11 के साथ संकलित मॉड्यूल का केवल तथ्य है और फिर अन्य सी ++ 11 कोड के खिलाफ जुड़ा हुआ है, यह दर्शाता है कि आपको गारंटी मिलेगी?

क्या किसी को भी एक अच्छा संदर्भ पता है जहां इस तरह के मुद्दे शामिल हैं?

+0

स्थैतिक प्रारंभिकरण एक भाषा संपत्ति है। मैं नहीं देखता कि यह एक विशिष्ट पुस्तकालय से कैसे प्रभावित हो सकता है। – pmr

+2

@pmr यह मेरे लिए थोड़ा मुश्किल लगता है क्योंकि - उदाहरण के लिए - उपर्युक्त स्थिर के लिए स्मृति कार्यक्रम की शुरुआत में आवंटित की जाती है, लेकिन कन्स्ट्रक्टर पहली बार कार्य के अंदर स्थिर के साथ फ़ंक्शन चलाता है। ऐसा करने के लिए अंतर्निहित थ्रेड मॉडल के बारे में एक सर्वज्ञता की आवश्यकता होगी, इसलिए मुझे संदेह है कि QThread/C++ 11thread को मिश्रित करने पर यह सही हो सकता है ... हालांकि नई बाइनरी आवश्यकताओं का मामूली मौका है जो इसे काम करता है । – HostileFork

+0

@ होस्टाइलफ़र्क: जब तक दोनों (सी ++ और क्यूटी) थ्रेडिंग के लिए एक ही ओएस सुविधाओं का उपयोग करते हैं, तो मुझे नहीं लगता कि कुछ गलत कैसे हो सकता है। इसके अलावा मुझे नहीं पता कि दोनों में से किसी को ओएस थ्रेडिंग सुविधाओं का उपयोग क्यों नहीं करना चाहिए। – PlasmaHH

उत्तर

4

आपका उदाहरण मेमोरी मॉडल पर निर्भर करता है, न कि धागे को कैसे लागू किया जाता है। जो भी इस कोड को निष्पादित करता है वह वही निर्देश निष्पादित करेगा। यदि दो या दो से अधिक कोर इस कोड को निष्पादित करते हैं, तो वे स्मृति मॉडल का पालन करेंगे।

बुनियादी कार्यान्वयन इस के बराबर है:

std::mutex mtx; 
Logger * lg = 0; 
Logger& g_logger() { 
    std::unique_lock<std::mutex> lck(mtx); 
    if (lg == 0) 
     lg = new Logger; 
    return *lg; 
} 

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

+0

कूल द्वारा प्रदान की गई गारंटी प्रदान करने पर भरोसा नहीं कर सकते हैं, धन्यवाद ... ऐसा लगता है कि यह सर्वसम्मति है कि यह * सुरक्षित * होना सुरक्षित है। एफवाईआई: जिस कारण में मैं इसे देख रहा था वह इस परिदृश्य को संबोधित करना था ... http://stackoverflow.com/questions/9507973/how-to-mitigate-user-facing-api-effect-of-shared-members-in -templated वर्गों – HostileFork

7

किसी को भी एक अच्छा संदर्भ जहां इस तरह की समस्या कवर कर रहे हैं पता है?

निश्चित रूप से। सी ++ मानक। यह सी ++ कोड के व्यवहार का वर्णन करता है। यदि आपकी लाइब्रेरी सी ++ कोड है, तो इस व्यवहार का पालन करना आवश्यक है। तो हाँ, आपको वही गारंटी मिलती है जैसे कि यह आपका स्वयं का कोड था।

सटीक रूप से कैसे संकलक/रनटाइम/ओएस/बाकी सब कुछ इसे खींचता है आपकी समस्या नहीं है। सी ++ मानक गारंटी देता है कि इसका ख्याल रखा जाता है।

+0

बिंदु के अनुसार निष्पादन के सभी मान्य धागे हैं। फिर भी चाहे यह मेरी समस्या है या नहीं, मैं जानना चाहूंगा कि क्या मैं जीसीसी और क्यूटी का उपयोग करता हूं अगर उन्होंने जादू को "इसे खींचने" के लिए किया था। एक तकनीकी दृष्टिकोण से, यदि एक सी ++ 03 'स्थिर है।एक पुस्तकालय को एक सी ++ 11 'icallthestatic' निष्पादन योग्य में जोड़ा गया था, यह संभव नहीं है कि लिंकर ऐसा करने में सक्षम होगा। लेकिन यह एक व्यापक मुद्दे को इंगित करता है "आप शायद सी ++ 11 कोड को सी ++ 11 से लिंक नहीं कर सकते हैं और सिस्टम के लिए सी ++ 11 गारंटी प्राप्त कर सकते हैं" ... – HostileFork

+0

सी ++ 03 कोड केवल व्यवहार करने की गारंटी है सी ++ 03 की तरह। तो यदि आप एक सी ++ 03 लाइब्रेरी से लिंक करते हैं, तो आप केवल सी ++ 11 – jalf