c++ - प्रोग्राम टर्मिनेशन(सी/सी++) पर फ़ाइल हटाने की गारंटी है




file termination (6)

अतीत में, मैंने एक "अस्थायी फ़ाइल प्रबंधक" बनाया है जो अस्थायी फ़ाइलों का ट्रैक रखता है।

कोई प्रबंधक से अस्थायी फ़ाइल नाम का अनुरोध करेगा और यह नाम पंजीकृत किया गया था।

एक बार जब आपको अस्थायी फ़ाइल नाम की आवश्यकता नहीं होती है, तो आप प्रबंधक को सूचित करते हैं और फ़ाइल नाम अपंजीकृत नहीं होता है

एक समाप्ति संकेत प्राप्त होने पर, सभी पंजीकृत अस्थायी फ़ाइलों को नष्ट कर दिया गया था।

टकराव से बचने के लिए अस्थायी फ़ाइल नाम यूयूआईडी थे।

Win32 के CreateFile में FILE_FLAG_DELETE_ON_CLOSE , लेकिन मैं लिनक्स पर हूं।

मैं एक अस्थायी फ़ाइल खोलना चाहता हूं जो कि प्रोग्राम समाप्ति पर हमेशा हटा दिया जाएगा मैं समझ सकता था कि एक कार्यक्रम दुर्घटना के मामले में यह गारंटी देने के लिए व्यावहारिक नहीं हो सकता है, लेकिन किसी भी अन्य मामले में मुझे यह काम करना चाहिए।

मैं आरएआई के बारे में जानता हूं मैं संकेतों के बारे में जानता हूं मैं atexit(3) बारे में पता है मुझे पता है कि मैं फ़ाइल खोल सकता हूं और इसे तुरंत हटा सकता हूं और फ़ाइल तब तक उपलब्ध रहेगी जब तक फाइल डिस्क्रिप्टर बंद नहीं हो जाता (जो भी क्रैश संभालता है)। इनमें से कोई भी एक पूर्ण और सरल समाधान की तरह नहीं दिखता है:

  1. RAII: वहां गया, यह किया गया: मेरे पास एक ऐसा ऑब्जेक्ट है जिसके डिस्ट्रिक्टर ने फ़ाइल को हटाया है, लेकिन डिस्ट्रक्टर नहीं कहा जाता है अगर प्रोग्राम सिग्नल द्वारा समाप्त होता है।
  2. सिग्नल: मैं एक निम्न स्तरीय लाइब्रेरी लिख रहा हूं जो एक सिग्नल हैंडलर को एक मुश्किल प्रस्ताव बताता है। उदाहरण के लिए, क्या होगा यदि अनुप्रयोग संकेतों का उपयोग करता है? मैं किसी भी पैर की उंगलियों पर कदम नहीं करना चाहता। मैं सामना करने के लिए sigaction(2) कुछ चतुर उपयोग पर विचार कर सकता हूं ... लेकिन अभी तक इस संभावना में पर्याप्त विचार नहीं लगाया है।
  3. atexit(3) : जाहिरा तौर पर बेकार, क्योंकि यह असामान्य समाप्ति (जैसे एक संकेत के माध्यम से) के दौरान नहीं कहा जाता है।
  4. रिक्तिपूर्व unlink(2) : यह बहुत अच्छा है सिवाय इसके कि मुझे फाइल सिस्टम में दिखाई देने के लिए फाइल की आवश्यकता है (अन्यथा सिस्टम को मॉनिटर / समस्या निवारण के लिए कठिन है)।

तुम यहाँ क्या करोगे?

आगे की व्याख्या

मैंने अपने मूल पोस्ट में एक विस्तार को लुभाने के लिए जो अब मुझे पता है कि मुझे शामिल होना चाहिए। इस मामले में "फ़ाइल" सख्ती से एक सामान्य फ़ाइल नहीं है, बल्कि एक POSIX संदेश कतार है। मैं इसे mq_open() माध्यम से बना रहा हूँ इसे mq_close() या close() द्वारा बंद किया जा सकता है (पूर्व मेरे सिस्टम पर उत्तरार्द्ध के लिए उपनाम है)। यह सिस्टम से mq_unlink() माध्यम से हटाया जा सकता है यह सब एक नियमित फाइल के अनुरूप बनाता है, सिवाय इसके कि मैं उस निर्देशिका का चयन नहीं कर सकता जिसमे फ़ाइल रहता है। यह वर्तमान सर्वाधिक लोकप्रिय उत्तर ( /tmp में फ़ाइल को रखे) अप्रभावी बना देता है, क्योंकि "फ़ाइल" सिस्टम द्वारा बहुत सीमित क्षमता वाले वर्चुअल फ़ाइल सिस्टम में बनाई जाती है। (मैंने वर्चुअल फाइल सिस्टम को /dev/mqueue , man mq_overview में उदाहरण के बाद)

यह भी बताता है कि मुझे दिखाई देने के लिए नाम की आवश्यकता क्यों है (तत्काल-अनलिंक करने के लिए अप्रभावी दृष्टिकोण): "फ़ाइल" को दो या अधिक प्रक्रियाओं के बीच साझा किया जाना चाहिए।


आप फ़ाइल बनाने के बाद प्रक्रिया कांका कर सकते हैं, और फिर बच्चे को बंद करने के लिए प्रतीक्षा करें, और फिर माता-पिता फाइल को अनलिंक कर सकते हैं और बाहर निकलें।


यदि आप बस एक अस्थायी फ़ाइल बना रहे हैं, तो उसे /tmp या उप-डायरेक्टरी में बनाएं तब इसे निकालने का सबसे अच्छा प्रयास करें जब atexit(3) या समान के माध्यम से किया जाए। जब तक आप mkstemp(3) या समान के माध्यम से चुना गया विशिष्ट नाम का उपयोग करते हैं, तब भी जब यह प्रोग्राम क्रैश के कारण हटाए जाने में विफल रहता है, तो आप इसे बाद के रनों या अन्य ऐसी स्थितियों पर फिर से पढ़ना जोखिम नहीं लेते हैं।

उस समय यह सिर्फ सिस्टम-स्तरीय समस्या /tmp साफ रखने की है अधिकांश डिस्टर्स इसे बूट या बंद करने पर पोंछते हैं, या पुरानी फाइलों को हटाने के लिए नियमित क्रोनोह चलाते हैं।


शायद किसी ने पहले से यह सुझाव दिया है, लेकिन मैं इसे खोज करने में असमर्थ हूं, आपकी सभी आवश्यकताओं को देखते हुए, सबसे अच्छा मैं सोच सकता हूं कि फ़ाइल नाम किसी भी तरह से एक प्रारंभिक स्क्रिप्ट जैसे कि एक प्रारंभिक स्क्रिप्ट के लिए भेजी जाती है, जो बाद में साफ़ हो जाएगा प्रक्रिया मर जाती है, क्या ऐसा करने में विफल रहा। यह शायद अधिकतर वॉचडॉग के रूप में जाना जाता है, लेकिन फिर अधिक सामान्य उपयोग के मामले में प्रक्रिया को मारने और / या पुनः आरंभ करने में जोड़ा जाता है जब यह किसी तरह विफल हो जाता है।

यदि आपकी मूल प्रक्रिया भी मर जाती है, तो आप बहुत भाग्य से बाहर हैं, लेकिन अधिकांश स्क्रिप्ट परिवेश काफी मजबूत हैं और शायद ही कभी मर जाते हैं जब तक कि स्क्रिप्ट टूट जाती न हो, जो प्रोग्राम के मुकाबले सही रखना आसान होता है।


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

मैं इसे किसी भी तरह से सरल करने के तरीके नहीं देख रहा हूँ यह बॉयलरप्लेट है जो किसी भी उत्पादन गुणवत्ता कार्यक्रम के माध्यम से जाना चाहिए; +500 लाइन आसानी से


क्या आपको वास्तव में नाम दिखने की आवश्यकता है?

मान लीजिए आप तुरंत फ़ाइल को अनलिंक करने का विकल्प लेते हैं। फिर:

  • रिक्तिपूर्व अनलिंक (2): यह बहुत अच्छा है सिवाय इसके कि मुझे फाइल सिस्टम में दिखाई देने के लिए फाइल की आवश्यकता है (अन्यथा सिस्टम को मॉनिटर / समस्या निवारण के लिए कठिन है)।

    आप अब भी हटाए गए फ़ाइल पर डिबग कर सकते हैं, क्योंकि यह अभी भी /proc/$pid/fd/ अंतर्गत दिखाई देगी जब तक आप अपनी प्रक्रियाओं के पाइड को जानते हैं, तब तक उनकी खुली फाइलों की गणना करना आसान होना चाहिए।

  • सामान्य ऑपरेशन के दौरान नामों को दिखना चाहिए क्योंकि उन्हें कार्यक्रमों के बीच साझा किया जाता है।

    आप अभी भी यूनिक्स डोमेन सॉकेट्स पर फ़ाइल डिस्क्रिप्टर पास कर प्रक्रियाओं के बीच हटाए गए फ़ाइल को साझा कर सकते हैं। अधिक जानकारी के लिए विभिन्न प्रक्रियाओं के बीच फाइल डिस्क्रिप्टर को पास करने का पोर्टेबल तरीका देखें।







unlink