2009-11-09 13 views
6

का उपयोग करके सरल सी ++ लॉगर सिंगलटन पैटर्न का उपयोग करके लॉगर को लागू करने के बाढ़ के उदाहरणों के कारण, मैंने अपने कार्यक्रम के लिए एक ही दृष्टिकोण में एक साधारण सी ++ लॉगर लिखा है। हालांकि, चूंकि प्रसिद्ध डबल-चेक लॉकिंग दृष्टिकोण को और अधिक थ्रेड-सुरक्षित नहीं माना जाता है, मुझे आश्चर्य है कि मुझे चाहिए:सिंगलटन पैटर्न

1) इस मामले में सिंगलटन पैटर्न के उपयोग के बारे में भूल जाओ?

2) डबल-चेक लॉकिंग का उपयोग करना जारी रखें, भले ही यह असुरक्षित है?

3) अपने सार्वजनिक इंटरफेस के हर एक्सेस के लिए महंगी शुद्ध सिंक लॉक विधि का उपयोग करें?

कोई सुझाव?

+1

वाह, मुझे उम्मीद नहीं थी कि प्रतिक्रिया इतनी तेजी से आती है। मुझे बस एहसास हुआ कि मैंने एक बेवकूफ गलती की है। मेरे मामले में इंटरफ़ेस के मूल रूप से दो समूह होते हैं जिन्हें सुरक्षा की आवश्यकता होती है: getInstance(), और बाकी लॉग लॉग क्लाइंट के लिए विभिन्न लॉग सेटिंग्स को प्रारंभ करने के लिए हैं। मेरी गलती यह थी कि, मैं एक ऐसे दृष्टिकोण को खोजने में काफी समय बिता रहा हूं जो संतुलित दक्षता के साथ दोनों प्रकार के इंटरफेस की रक्षा करेगा। मुझे एक का उपयोग क्यों करना चाहिए, और केवल एक दृष्टिकोण? मैं getInstance() के लिए या तो Arkaitz या Stefaanv से सुझाव का उपयोग कर सकते हैं; फिर सेटिंग प्रारंभ करने के लिए मूल सिंक लॉक का उपयोग करें। – shiouming

उत्तर

16

मेयर्स सिंगलटन का उपयोग करें। यदि आप कम से कम प्रारंभिक जीसीसी का उपयोग कर उपयोग कर रहे हैं तो थ्रेड-सुरक्षित है।

class Singleton{ 
    Singleton(){ 
    //This is threadsafe in gcc, no mutex required 
    } 
    static Singleton * instance(){ 
     static Singleton myinstance; 
     return &myinstance; 
    } 
}; 

जीसीसी गार्ड स्थिर स्थानीय लोगों निर्माण जब तक आप -fno-threadsafe-स्टैटिक्स के साथ अक्षम करें, मैं हाल ही में है कि here

+0

क्या आप उदाहरण() स्थिर नहीं होना चाहते हैं? – Aaron

+0

हारून, आप सही हैं। इस नोट के लिए –

+0

+1, मैंने एक बार विंड्रिवर सी/सी ++ कंपाइलर (पूर्व डायब) के साथ इस समस्या के आसपास पर्याप्त समय बिताया। –

1

बारे में लिखा था धागे के साथ अनुप्रयोगों में, मैं कोई Initialize() समारोह के साथ एकमात्र उपयोग करने के लिए पसंद करते हैं और यह सुनिश्चित करने के लिए जोर देता है कि प्रारंभिक() पहले उदाहरण() से पहले उपयोग किया जाता है। मुख्य धागे से प्रारंभ() प्रारंभ करें। मुझे नहीं लगता कि आलसी तात्कालिकता वास्तव में एक सिंगलटन की मुख्य विशेषता है, खासकर लॉगर के लिए।

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

+0

मुझे यह जवाब पसंद है, लेकिन चेतावनी के साथ कि आप प्री-प्रारंभिक कोड के दौरान लॉगिंग का उपयोग नहीं कर सकते हैं। यह आमतौर पर एक बड़ा सौदा नहीं है, लेकिन मैंने इसे एक या दो बार काट दिया है। –

+0

@ माइकल: जब हमने इस दृष्टिकोण के लिए निर्णय लिया, तो मैंने वास्तव में आपके उत्तर का उपयोग करने का सुझाव दिया: मुख्य धागे में प्रवेश करना। लेकिन यह दृष्टिकोण हमारे लिए काम करता है और यह सुनिश्चित करता है कि सिंगलटन हमेशा मुख्य धागे में प्रारंभ होता है। यदि मुख्य धागे से पहुंच हटा दी जाएगी, तो हमें केवल पहली बार समस्या होगी (फ़ील्ड में?) – stefaanv

+0

मेरा मौजूदा कोड इस दृष्टिकोण के बहुत करीब है। हालांकि, मैं यह भी सोच रहा हूं कि मुझे यह मानना ​​चाहिए कि लॉगर का क्लाइंट कोड हमेशा लॉगर का सही उपयोग/प्रारंभ करेगा, या मुझे आंतरिक रूप से कोई जांच करनी चाहिए। – shiouming

1

एक दृष्टिकोण यह सुनिश्चित करना होगा कि आपके ऐप को दूसरी थ्रेड शुरू होने से पहले लॉगर में आपकी पहली पहुंच आती है। एक समय में सिंगलटन तक पहुंचने पर जब आप जानते हैं कि कोई विवाद नहीं है, तो आप सुनिश्चित करते हैं कि बाद में पहुंच हमेशा एक पूर्व-मौजूद वस्तु पाएगी और आपको पूरी तरह से समस्या से बचना चाहिए।

0

आपको वास्तव में अलग प्रारंभ() फ़ंक्शन की आवश्यकता नहीं है क्योंकि यह आपके सिंगलटन इंटरफ़ेस को दूषित कर देगा। बस सिंगलटन इंस्टेंस

VERIFY(NULL != Logger::Instance()); 

किसी अन्य थ्रेड से पहले इसे एक्सेस करने का मौका मिलता है।

+0

आपको न्यूल के लिए सिंगलटन की जांच करने की आवश्यकता नहीं है। यह अस्तित्व में है या यह बाहर नहीं निकलता है। सिंगलटन गुरुत्वाकर्षण के संदर्भ में यह लौट रहा है। –

+0

धन्यवाद मार्क। मैं मानता हूं कि सिंगलटन गेटर को संदर्भ वापस नहीं करना चाहिए, पॉइंटर नहीं। मेरी रेखा उपरोक्त मेयर्स सिंगलटन के बारे में फिसल गई है जो इसे सूचक द्वारा वापस कर देती है। हालांकि ऐसा प्रतीत होता है कि यह असफल नहीं हो सकता है, आप कभी नहीं जानते कि सड़क के नीचे आपका कोड कौन संशोधित करेगा। तो भविष्य में प्रोग्रामर के लिए यहां एक समय कैप्सूल है। – BostonLogan

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