2014-11-03 6 views
5

एकाधिक (पॉज़िक्स) थ्रेड exit() समानांतर में कॉल करते समय मैं स्थिर सी ++ ऑब्जेक्ट्स को सुरक्षित रूप से कैसे हटा सकता हूं?सुरक्षित स्थैतिक विनाशक जब एकाधिक धागे बाहर निकलें()

यह मेरी CentOS6 वातावरण में प्रतीत होता है कि exit()fct[--cnt]() की तरह कुछ जहां cnt पंजीकृत संचालकों की संख्या है फोन करके कार्यान्वित atexit (या on_exit) सफाई संचालकों। जब कई धागे एक ही समय में exit() पर कॉल करते हैं, तो हमारे पास असुरक्षित --cnt ऑपरेशन में दौड़ की स्थिति होती है और कुछ हैंडलर को छोड़ दिया जा सकता है या कई बार बुलाया जा सकता है (कभी-कभी क्रैश होता है)। तो मैं कैसे सुनिश्चित कर सकता हूं कि exit() कॉलिंग थ्रेड में से केवल एक क्लीनअप करता है और बाकी सभी बंद हो जाते हैं? ध्यान दें कि एक सफाई हैंडलर में एक pthread_mutex_lock() डालने में मदद नहीं करता है क्योंकि इस हैंडलर छोड़ी नहीं जा सकती है ...

दुर्भाग्य से मैं टाल नहीं सकते कि एक से अधिक थ्रेड फोन exit() क्योंकि उस कोड मेरी उन लिखेंगे (मैं एक प्रदान कर रहा हूँ है उन्हें पुस्तकालय)।

सुरक्षित विचारों की तलाश में, धन्यवाद!

+1

आप किस बारे में चिंतित हैं? क्या आपके पास अपनी स्थाई आवंटित वस्तुओं में कुछ है जो स्थापित होना चाहिए (यदि ऐसा है तो)? आधुनिक परिष्कृत ओएस में सफाई के बिना बाहर निकलना आम तौर पर सुरक्षित है। यदि आपको क्लीनअप करना है, तो मैं सुझाव दूंगा कि आपको शायद अपने क्लाइंट कोड कॉल से बाहर निकलने के बजाय बेहतर समाधान ढूंढने की आवश्यकता हो - जैसे कि साझा लाइब्रेरी में अपना कोड लागू करें, और साझा लाइब्रेरी क्लीनअप फ़ंक्शन को साफ़ करने के लिए उपयोग करें, शायद ? या दस्तावेज है कि "आपको बाहर निकलना नहीं है()', 'my_safe_exit()' "का उपयोग करें, और फिर देखें कि जब ग्राहक शिकायत करते हैं कि यह काम नहीं करता है। –

+0

उपर्युक्त के अतिरिक्त, क्या होगा यदि आपके ग्राहक बाहर निकलने के बिना डीबगर में क्रैश हो रहे हैं (स्टैक गलती, सीईजी गलती) या डिबगिंग और बाहर निकलना? –

+0

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

उत्तर

0

आप जीसीसी का उपयोग कर रहे हैं, तो आप नीचे दिए गए कोड एक सफाई प्रक्रिया को परिभाषित करने के लिए उपयोग कर सकते हैं:

void __attribute__ ((destructor)) my_fini(void); 

इस, आपकी समस्या का समाधान नहीं है, तो कैसे स्थिर अवधि जिसका नाशक के साथ एक वस्तु परिभाषित करने के बारे आपकी सफाई का ख्याल रखेगा?

1

बाहर निकलने के लिए कई कॉलों को संभालने के लिए कोई पोर्टेबल तरीका नहीं है() - क्योंकि यह उस मामले में क्या होता है अपरिभाषित (व्यवहार) होता है।

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

template <typename T> class StaticExitHandled { 
public: 
    std::unique_ptr<T> t_; 
    ~StaticExitHandled() { t_.release(); } 
}; 

अब इस टेम्पलेट के साथ अपनी सभी स्थिर वस्तुओं को घोषित करना याद रखें। यह सिर्फ इसका मूल है, अपने स्वाद के अनुसार घंटी और सीटी जोड़ें। इसके अलावा, std :: unique_ptr <> के बजाय आप boost :: वैकल्पिक <> या ऐसी कुछ चीज़ों का उपयोग कर सकते हैं।

मुझे नहीं लगता कि "बिल्कुल नहीं कहा जाता" के लिए एक सामान्य समाधान है।

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

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