क्यों एक vfork या कांटा के बच्चे को बाहर निकलने के बजाय _exit () कॉल करना चाहिए?


12

के मैन पेज से vfork():

vfork () कांटा () से भिन्न होता है, जिसमें अभिभावक को तब तक निलंबित रखा जाता है जब तक कि बच्चा कॉल करने के लिए निष्पादित नहीं करता है (2) या _exit (2)। बच्चा अपने माता-पिता के साथ सभी मेमोरी साझा करता है, जिसमें स्टैक शामिल है, जब तक कि बच्चे द्वारा निष्पादित () नहीं किया जाता है। बच्चे को वर्तमान फ़ंक्शन से वापस नहीं आना चाहिए या कॉल आउट () नहीं करना चाहिए, लेकिन _exit () को कॉल कर सकता है।

बच्चे को _exit()केवल फोन करने के बजाय क्यों इस्तेमाल करना चाहिए exit()? मुझे उम्मीद है कि यह vfork()और दोनों पर लागू होगा fork()


जवाबों:


11

जैसा कि पहले देखा गया है , vforkबच्चे की प्रक्रिया को माता-पिता की स्मृति तक पहुंचने की अनुमति नहीं देता है। exitएक सी लाइब्रेरी फंक्शन है (इसीलिए इसे अक्सर लिखा जाता है exit(3))। यह विभिन्न सफाई कार्य करता है जैसे फ्लशिंग और सी स्ट्रीम को बंद करना (घोषित कार्यों के माध्यम से खुली हुई फाइलें stdio.h) और पंजीकृत उपयोगकर्ता-निर्दिष्ट कार्यों को निष्पादित करना atexit। इन सभी कार्यों में प्रक्रिया मेमोरी को पढ़ना और लिखना शामिल है।

_exitसफाई के बिना बाहर निकलता है। यह सीधे एक सिस्टम कॉल है (यही वजह है कि इसे लिखा गया है _exit(2)), आमतौर पर एक प्रोसेसर रजिस्टर में सिस्टम कॉल नंबर को लागू करके और एक विशेष प्रोसेसर निर्देश को निष्पादित करते हैं (सिस्टम कॉल हैंडलर के लिए शाखा)। यह प्रक्रिया मेमोरी तक पहुंचने की आवश्यकता नहीं है, इसलिए यह बाद में करना सुरक्षित है vfork

इसके बाद fork, इस तरह का कोई प्रतिबंध नहीं है: माता-पिता और बच्चे की प्रक्रिया अब पूरी तरह से स्वायत्त है।


vfork बच्चे की प्रक्रिया को माता-पिता की स्मृति तक पहुंचने की अनुमति नहीं देता है ? लेकिन मुझे लगा कि वे एक ही पते की जगह साझा करते हैं, इसलिए बच्चा माता-पिता के पते की जगह तक पहुंच सकता है। क्या वह समझ गलत थी?
सेन

कांटे के बाद, इस तरह का कोई प्रतिबंध नहीं है: माता-पिता और बच्चे की प्रक्रिया अब पूरी तरह से स्वायत्त है। क्या इसका मतलब है कि मैं एक कांटे के बच्चे से एक निकास () कह सकता हूं ?
सेन

1
@ सीन: बच्चे को माता-पिता की स्मृति तक पहुंचने की अनुमति नहीं है। यदि आप इसे आज़माते हैं, तो यह काम कर सकता है, क्योंकि कर्नेल आपकी रक्षा नहीं करेगा। लेकिन प्रभाव वह नहीं हो सकता जो आप चाहते हैं; उदाहरण के लिए, यदि आपका संकलक किसी रजिस्टर में कुछ मूल्य छोड़ने का फैसला करता है, तो यह मूल प्रक्रिया द्वारा नहीं देखा जाएगा।
गिल्स एसओ- बुराई को रोकना '

@ सीन: कांटे के बाद, आप कॉल एक्जिट या किसी अन्य फंक्शन कर सकते हैं। प्रत्येक प्रक्रिया एक कांटा (लिनक्स पर, यहां तक ​​कि प्रारंभिक प्रक्रिया initकर्नेल द्वारा कांटा जाता है) के बाद शुरू होती है ।
गिल्स एसओ- बुराई को रोकना '

3

exitअतिरिक्त क्लीनअप जैसे कॉलिंग फ़ंक्शंस पंजीकृत हैं, जिससे atexitयह कॉपी किए गए भाग के बाहर डेटा एक्सेस करता है। _exitकिसी भी क्लीनअप को सीधे इन-कर्नेल को छोड़कर syscall करता है।


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

3

जब बच्चा प्रक्रिया से बाहर निकलता है तो आप बच्चे को फ्लिक्सिंग (या अन्य) बफ़र्स से बचने के लिए _exit () कॉल करते हैं। चूंकि बच्चे की प्रक्रिया माता-पिता की प्रक्रिया की एक सटीक प्रतिलिपि का गठन करती है, इसलिए बच्चे की प्रक्रिया में अभी भी जो कुछ भी माता-पिता के पास "stdout" या "stderr" है, बफ़र्स <stdio.h> से है। आप (और, इनोपपोर्ट्यून समय में) एक्ज़िट कॉल करके डबल आउटपुट प्राप्त कर सकते हैं (), चाइल्ड प्रोसेस के एटैक्सिट हैंडलर्स में से एक, और पेरेंट से एक, जब पेरेंट प्रोसेस में बफ़र फुल हो जाते हैं, और फ्लश हो जाता है।

मुझे लगता है कि उपरोक्त उत्तर में stdio.h बारीकियों पर ध्यान केंद्रित किया गया है, लेकिन यह विचार संभवतः अन्य बफ़र किए गए I / O को वहन करता है, जैसा कि ऊपर दिए गए उत्तर में से एक इंगित करता है।


1

exit(): - कुछ सफाई कार्य करता है, जैसे कि i / o स्ट्रीम और कई को बंद करना, और फिर कर्नेल पर लौटना। _exit(): - सीधे कर्नेल आता है (कोई भी सफाई कार्य नहीं करना)।

fork() : माता-पिता और बच्चे दोनों के पास अलग-अलग फ़ाइल तालिका होती है, इसलिए बच्चे द्वारा किए गए परिवर्तन से माता-पिता के पर्यावरण मापदंडों को प्रभावित नहीं होता है, और इसके विपरीत।

vfork(): माता-पिता और बच्चे दोनों एक ही फाइल टेबल का उपयोग करते हैं, इसलिए बच्चे द्वारा किया गया परिवर्तन माता-पिता के पर्यावरण मापदंडों को प्रभावित करता है। उदाहरण के लिए, कुछ चर var=10, अब var++बच्चे द्वारा चलाए जाते हैं और फिर माता-पिता को चलाते हैं, आप माता-पिता var++के आउटपुट में भी प्रभाव देख सकते हैं ।

जैसा कि मैंने कहा कि यदि आप उपयोग करते exit()हैं vfork()तो सभी i / o पहले से ही बंद हैं। तो फिर, अगर माता-पिता सही तरीके से चलते हैं, तो भी आप उचित आउटपुट प्राप्त करने में सक्षम नहीं हो सकते, क्योंकि सभी चर प्रवाहित हो जाते हैं और सभी धाराएँ बंद हो जाती हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.