2010-03-11 10 views
7

यूनिक्स पर्यावरण में उन्नत प्रोग्रामिंग में पाइप के बारे में पढ़ते समय, मैंने देखा कि एक कांटा के बाद माता-पिता close() पाइप के पढ़ने के अंत कर सकते हैं और यह पढ़ने के अंत को बंद नहीं करता है बच्चा। जब एक प्रक्रिया कांटा, क्या इसकी फाइल डिस्क्रिप्टर बनाए रखा जाता है?एक कांटा के बाद एक पाइप का व्यवहार()

मेरा मतलब यह है कि कांटे से पहले पाइप पढ़ने के लिए फ़ाइल डिस्क्रिप्टर की गिनती 1 थी, और कांटा के बाद 2. जब माता-पिता ने अपनी पढ़ाई की ओर बंद कर दिया तो एफडी 1 तक चला गया और इसे खोलने के लिए खुला रखा गया बच्चे। क्या यह अनिवार्य रूप से हो रहा है? क्या यह व्यवहार नियमित फ़ाइल वर्णनकर्ताओं के लिए भी होता है?

उत्तर

5

एक fork() के बारे में आदमी पृष्ठ पर पढ़ सकते हैं के रूप में:

बच्चे माता-पिता की प्रक्रिया फ़ाइल वर्णनकर्ता की अपनी एक प्रतिलिपि होगा। प्रत्येक बच्चे की फ़ाइल डिस्क्रिप्टर अभिभावक के संबंधित फ़ाइल वर्णनकर्ता के साथ खुली फ़ाइल विवरण का संदर्भ लेंगी।

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

+0

... जब तक आप http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html (जो आपको नहीं करना चाहिए, यह नहीं है) के साथ कुछ चालबाजी नहीं करते हैं – ephemient

+0

निश्चित रूप से, लेकिन क्या आपने पोस्ट किया है 'कांटा() 'लेकिन इसका एक बदलाव नहीं है। – pajton

+0

नहीं, मेरा मतलब है कि 'pthread_atfork' प्रोग्राम के कार्यों को 'फोर्क' समय पर बदल सकता है (उदाहरण के लिए) बंद फ़ाइल डिस्क्रिप्टर शामिल हैं। लेकिन डिफ़ॉल्ट रूप से ऐसा नहीं होता है, और किसी भी तरह इंटरफ़ेस का दुरुपयोग करना एक अजीब चीज है। – ephemient

1

हां, एक कांटा सभी खुले फ़ाइल वर्णनकर्ताओं को डुप्लिकेट करता है।

तो एक सामान्य पाइप के लिए, 2 स्लॉट सरणी (int fd [2]), fd [0] माता-पिता और बच्चे के लिए समान है, और इसलिए fd [1] है।

आप बिना किसी प्रक्रिया के एक पाइप बना सकते हैं, और एक प्रक्रिया में fd [0] और fd [1] का उपयोग करके स्वयं को पढ़/लिख सकते हैं।

+1

भयानक के लिए अग्रणी http://cr.yp.to/docs/selfpipe.html चाल! – ephemient

2

उत्तर हाँ है, और हाँ (यह सभी फाइल डिस्क्रिप्टरों पर लागू होता है, जिसमें सॉकेट जैसी चीजें शामिल हैं)।

fork() कॉल में, बच्चे को प्रत्येक फ़ाइल डिस्क्रिप्टर की अपनी अलग प्रति प्राप्त होती है, कि प्रत्येक कार्य जैसे उन्हें dup() द्वारा बनाया गया था। close() केवल पारित विशिष्ट फ़ाइल डिस्क्रिप्टर को बंद कर देता है - उदाहरण के लिए यदि आप n2 = dup(n); close(n); करते हैं, तो फ़ाइल (पाइप, सॉकेट, डिवाइस ...) n खुला रहता है - यह fork() द्वारा डुप्लीकेट फ़ाइल डिस्क्रिप्टर पर लागू होता है ।

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