जब आप कॉल करते हैं vfork()
, तो एक नई प्रक्रिया बनाई जाती है और यह नई प्रक्रिया स्टैक के अपवाद के साथ मूल प्रक्रिया की छवि को उधार लेती है। बच्चे की प्रक्रिया को एक नया स्टैक स्टार दिया जाता है, हालांकि return
उस फ़ंक्शन से अनुमति नहीं देता है जिसे कॉल किया जाता है vfork()
।
जब बच्चा चल रहा होता है, तो माता-पिता की प्रक्रिया अवरुद्ध हो जाती है, क्योंकि बच्चा माता-पिता के पते की जगह उधार लेता है।
आप जो भी करते हैं, उसके बावजूद जो कुछ भी स्टैक तक पहुंचता है, वह केवल बच्चे के निजी स्टैक को संशोधित करता है। यदि आप हालांकि वैश्विक डेटा को संशोधित करते हैं, तो यह सामान्य डेटा को संशोधित करता है और इस प्रकार यह माता-पिता को भी प्रभावित करता है।
वैश्विक डेटा को संशोधित करने वाली चीजें उदाहरण के लिए हैं:
कॉलिंग मॉलोक () या मुफ़्त ()
stdio का उपयोग कर
सिग्नल सेटिंग्स को संशोधित करना
परिवर्तनशील चर जो उस फ़ंक्शन के लिए स्थानीय नहीं हैं जिन्हें कॉल किया गया है vfork()
।
...
एक बार जब आप कॉल करते हैं _exit()
(महत्वपूर्ण, कभी कॉल नहीं करते हैं exit()
), तो बच्चे को समाप्त कर दिया जाता है और नियंत्रण वापस माता-पिता को दे दिया जाता है।
यदि आप exec*()
परिवार से किसी भी फ़ंक्शन को कॉल करते हैं , तो एक नया पता स्थान नए प्रोग्राम कोड, नए डेटा और माता-पिता से स्टैक के एक हिस्से (नीचे देखें) के साथ बनाया गया है। एक बार यह तैयार हो जाने के बाद, बच्चा अब बच्चे से पता स्थान उधार नहीं लेता है, बल्कि खुद के पते की जगह का उपयोग करता है।
अभिभावक को नियंत्रण वापस दिया जाता है, क्योंकि यह पता स्थान अब किसी अन्य प्रक्रिया द्वारा उपयोग में नहीं है।
महत्वपूर्ण: लिनक्स पर, कोई वास्तविक vfork()
कार्यान्वयन नहीं है। सन 1988 में SunOS-4.0 द्वारा शुरू की गई कांसेप्ट vfork()
पर fork()
लिखी गई अवधारणा पर आधारित लिनक्स पर लागू होने के बावजूद । उपयोगकर्ताओं को यह विश्वास दिलाने के लिए कि वे उपयोग करते हैं vfork()
, लिनक्स सिर्फ साझा किए गए डेटा को सेट करता है और माता-पिता को निलंबित कर देता है, जबकि बच्चा फोन नहीं करता था _exit()
या किसी एक exec*()
कार्य करता था।
इसलिए लिनक्स इस तथ्य से लाभ नहीं उठाता है कि एक वास्तविक vfork()
को कर्नेल में बच्चे के लिए पता स्थान विवरण सेट करने की आवश्यकता नहीं है। इस में परिणाम vfork()
तेजी से नहीं है fork()
। वास्तविक लागू करने वाली प्रणालियों पर vfork()
, यह आमतौर पर की तुलना में तेजी से 3x होता है fork()
और उपयोग किए जाने वाले गोले के प्रदर्शन को प्रभावित करता है vfork()
- ksh93
, हाल ही में Bourne Shell
और csh
।
एड चाइल्ड exit()
से आपको कभी भी कॉल नहीं करना चाहिए , क्योंकि कॉल करने से पहले फ्लश करने की स्थिति में फ्लश स्टीडियो होता है । इससे अजीब परिणाम हो सकते हैं।vfork()
exit()
vfork()
BTW: के posix_spawn()
शीर्ष पर लागू किया जाता है vfork()
, इसलिए vfork()
OS से हटाया नहीं जा रहा है। यह उल्लेख किया गया है कि लिनक्स का उपयोग नहीं करता vfork()
के लिए posix_spawn()
।
स्टैक के लिए, कुछ दस्तावेज हैं, यहां सोलारिस मैन पेज कहते हैं:
The vfork() and vforkx() functions can normally be used the
same way as fork() and forkx(), respectively. The calling
procedure, however, should not return while running in the
child's context, since the eventual return from vfork() or
vforkx() in the parent would be to a stack frame that no
longer exists.
इसलिए कार्यान्वयन को जो पसंद है वह कर सकता है। Solaris कार्यान्वयन फ़ंक्शन कॉलिंग के स्टैक फ्रेम के लिए साझा मेमोरी का उपयोग करता है vfork()
। कोई भी कार्यान्वयन माता-पिता से स्टैक के पुराने हिस्सों तक पहुंच नहीं देता है।