जब मैं फ़ाइल डिस्क्रिप्टर बंद करता हूं तो क्या होता है?


16

मैं फ़ाइल डिस्क्रिप्टर के साथ पूरी तस्वीर प्राप्त करने की कोशिश कर रहा हूं। कहो मेरे पास process1 है जिसमें शुरू में ये फाइल डिस्क्रिप्टर हैं:

 _process1_
|          |
| 0 stdin  |
| 1 stdout |
| 2 stderr |
|__________|

फिर मैंने फाइल डिस्क्रिप्टर 1 को बंद कर दिया:

close(1);

फ़ाइल डिस्क्रिप्टर 1 कर्नेल की ओपन फाइल्स टेबल में Stdout FILE स्ट्रक्चर में ट्रांसलेट (पॉइंट) करता है ।

फ़ाइल डिस्क्रिप्टर के ऊपर कोड के साथ 1 प्रक्रिया की तालिका से हटा दिया जाता है जो बन जाती है:

 _process1_
|          |
| 0 stdin  |
| 2 stderr |
|__________|

लेकिन कर्नेल में क्या होता है? क्या stdoutFILE संरचना से निपटा जाता है? यह कैसे संभव है यदि stdout एक विशेष फ़ाइल (मॉनिटर) है और संभवतः अन्य प्रक्रियाओं द्वारा उपयोग की जा रही है? FILE संरचनाओं के बारे में क्या है जो सिर्फ सामान्य फाइलें हैं (उदाहरण के लिए .xt)? क्या होगा यदि ऐसी फाइल का उपयोग अन्य प्रक्रिया द्वारा किया जा रहा है?

जवाबों:


13

फ़ाइल डिस्क्रिप्टर 1 कर्नेल की ओपन फाइल्स टेबल में stdout FILE संरचना में अनुवाद करता है।

यह गलतफहमी है। कर्नेल की फ़ाइल तालिका का उपयोगकर्ता-स्पेस फ़ाइल संरचनाओं से कोई लेना-देना नहीं है।

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

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

एक संसाधन को जारी करने के लिए एक प्रक्रिया के लिए कोई मौका नहीं है एक और प्रक्रिया का उपयोग कर रहा है क्योंकि साझा संसाधनों को संदर्भ में गिना जाता है।


मुझे आपके उत्तर में शब्दावली की समझ के साथ थोड़ी कठिनाई है। मैं अनुमान लगा रहा हूं कि फ़ाइल पॉइंटर का अर्थ है "फ़ाइल ऑफ़सेट"। क्या आपका आशय यही था? इसके अलावा आप फ़ाइल हैंडल से क्या मतलब है ?
गीक

यह सही है, "फ़ाइल ऑफसेट" से मेरा मतलब है कि ऑफसेट, जिस पर बाद में पढ़ा या लिखा जाएगा। एक "फ़ाइल हैंडल" एक प्रक्रिया और एक खुली फ़ाइल विवरण के बीच एक कड़ी है - यह वही है जो आपको openसफल होने पर वापस मिलता है ।
डेविड श्वार्ट्ज

6

इस मामले में बहुत कुछ नहीं होगा। stdin, stdout, और stderr सभी एक ही फाइल डिस्क्रिप्टर के क्लोन बनते हैं। फ़ाइल डिस्क्रिप्टर के लिए संदर्भ काउंटर को एक से घटाया जाएगा। एक ही फाइल डिस्क्रिप्टर आमतौर पर शेल द्वारा आयोजित किया जाता है जिसमें से प्रोग्राम चलाया गया था, इसलिए फाइल डिस्क्रिप्टर को रखने की आवश्यकता है।

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

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


1
दो प्रश्न: (1) क्या फाइल डिस्क्रिप्टर वास्तव में री-काउंटेड हैं? जब आप नियंत्रण-डी ए करते हैं cat > some.file, तो स्टड पर बिल्ली को ईओएफ मिलता है, लेकिन शेल नहीं होता है। (२) संदर्भ गणना क्यों? क्यों नहीं कूड़ा संग्रह का कुछ रूप? क्या GC उपयोगकर्ता स्थान में बेहतर नहीं है?
ब्रूस एडिगर

बिलथोर के उत्तर पर विस्तार: सामान्य मामलों में स्टडआउट, स्टडआउट और स्टेटरर टीटीटी डिवाइस के लिए केवल खुले फ़ाइल हैंडल हैं। इसलिए यदि आप फ़ाइल हैंडल बंद करते हैं, तो वह TTY डिवाइस अभी भी है, और बाद में फिर से खोला जा सकता है।
पैट्रिक

1
@BruceEdiger: (1) जब शेल चलता है cat > some.fileतो वास्तव में जो कर रहा है, वह 'कुछ.फाइल' को खोलने और इसे डिस्क्रिप्टर 1 को फाइल करने के लिए असाइन करता है, तब यह करता है exec("cat")। जब कोई प्रक्रिया निष्पादित होती है (d), तो यह ओपन फाइल डिस्क्रिप्टर को इनहेरिट करता है।
पैट्रिक

@BruceEdiger (2) संदर्भ गणना कचरा संग्रह का एक पूर्ण रूप से ठीक प्रकार है जब इसका उपयोग डेटा संरचनाओं पर किया जाता है जिसमें एक ही प्रकार के अन्य डेटा संरचनाओं में पॉइंटर्स टू (या पॉइंटर्स की श्रृंखला समाप्त) नहीं होती है। इसके अलावा, यह कर्नेल स्पेस में हो रहा है (ऐसा नहीं है कि यह बहुत मायने रखता है)।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.