process - कांटा(), vfork(), exec() और क्लोन() के बीच का अंतर




clone (4)

  1. fork() - एक नई बाल प्रक्रिया बनाता है, जो मूल प्रक्रिया की पूरी प्रति है। बाल और अभिभावक प्रक्रियाएं विभिन्न आभासी पता रिक्त स्थान का उपयोग करती हैं, जो प्रारंभ में उसी स्मृति पृष्ठों द्वारा पॉप्युलेट की जाती हैं। फिर, चूंकि दोनों प्रक्रियाओं को निष्पादित किया जाता है, वर्चुअल एड्रेस रिक्त स्थान अधिक से अधिक भिन्न होने लगते हैं, क्योंकि ऑपरेटिंग सिस्टम इन दो प्रक्रियाओं में से किसी एक द्वारा लिखे गए मेमोरी पृष्ठों की आलसी प्रतिलिपि करता है और संशोधित पृष्ठों की एक स्वतंत्र प्रतियां निर्दिष्ट करता है प्रत्येक प्रक्रिया के लिए स्मृति। इस तकनीक को कॉपी-ऑन-लिखित (गाय) कहा जाता है।
  2. vfork() - एक नई बाल प्रक्रिया बनाता है, जो मूल प्रक्रिया की "त्वरित" प्रति है। सिस्टम कॉल fork() विपरीत, बच्चे और अभिभावक प्रक्रियाएं समान वर्चुअल एड्रेस स्पेस साझा करती हैं। ध्यान दें! समान वर्चुअल एड्रेस स्पेस का उपयोग करते हुए, क्लासिक fork() के मामले में माता-पिता और बच्चे दोनों एक ही स्टैक, स्टैक पॉइंटर और निर्देश पॉइंटर का उपयोग करते हैं! माता-पिता और बच्चे के बीच अवांछित हस्तक्षेप को रोकने के लिए, जो एक ही स्टैक का उपयोग करते हैं, पैरेंट प्रक्रिया का निष्पादन तब तक जमे हुए है जब तक कि बच्चा या तो निष्पादित नहीं करेगा exec() (एक नया वर्चुअल एड्रेस स्पेस और एक अलग स्टैक में संक्रमण) या _exit() (प्रक्रिया निष्पादन की समाप्ति)। vfork() "कांटा-और-निष्पादन" मॉडल के लिए fork() का अनुकूलन है। यह fork() से 4-5 गुना तेजी से किया जा सकता है, क्योंकि fork() (गाय के साथ भी गाय के साथ fork() विपरीत, vfork() सिस्टम कॉल के कार्यान्वयन में एक नई पता स्थान (निर्माण का निर्माण शामिल नहीं है vfork() आवंटन और नई पेज निर्देशिकाओं की स्थापना)।
  3. clone() - एक नई बाल प्रक्रिया बनाता है। इस सिस्टम कॉल के विभिन्न पैरामीटर, निर्दिष्ट करें कि मूल प्रक्रिया के कौन से हिस्सों को बाल प्रक्रिया में कॉपी किया जाना चाहिए और उनके बीच कौन से हिस्से साझा किए जाएंगे। नतीजतन, इस सिस्टम कॉल का उपयोग सभी प्रकार की निष्पादन इकाइयों को बनाने के लिए किया जा सकता है, जो धागे से शुरू होते हैं और पूरी तरह से स्वतंत्र प्रक्रियाओं से परिष्करण करते हैं। वास्तव में, clone() सिस्टम कॉल आधार है जिसका उपयोग pthread_create() और fork() सिस्टम कॉल के सभी परिवार के कार्यान्वयन के लिए किया जाता है।
  4. exec() - प्रक्रिया, भार और पार्स निर्दिष्ट निष्पादन योग्य बाइनरी की सभी मेमोरी रीसेट करता है, नए स्टैक सेट करता है और लोड निष्पादन योग्य के प्रवेश बिंदु पर नियंत्रण पास करता है। यह सिस्टम कॉल कॉलर को कभी भी नियंत्रण नहीं देता है और पहले से ही मौजूदा प्रक्रिया में एक नया प्रोग्राम लोड करने के लिए कार्य करता है। fork() सिस्टम कॉल के साथ यह सिस्टम कॉल एक क्लासिकल यूनिक्स प्रोसेस मैनेजमेंट मॉडल बनाता है जिसे "फोर्क-एंड-एक्जिक" कहा जाता है।

मैं Google पर इन चारों के बीच का अंतर ढूंढ रहा था और मुझे उम्मीद थी कि इस पर बड़ी मात्रा में जानकारी होगी, लेकिन वास्तव में चार कॉलों के बीच कोई ठोस तुलना नहीं थी।

मैंने इन सिस्टम कॉल के बीच मतभेदों को देखने के लिए एक तरह की बुनियादी संरचना को संकलित करने की कोशिश करने के बारे में सेट किया है और यहां मुझे जो मिला है। क्या यह सारी जानकारी सही है / क्या मुझे कुछ भी महत्वपूर्ण याद आ रही है?

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

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

Vfork : vfork और कांटा के बीच मूल अंतर यह है कि जब vfork () के साथ एक नई प्रक्रिया बनाई जाती है, तो मूल प्रक्रिया अस्थायी रूप से निलंबित कर दी जाती है, और बच्चे की प्रक्रिया माता-पिता की पता स्थान उधार ले सकती है। मामलों की यह अजीब स्थिति तब तक जारी है जब तक कि बच्चे की प्रक्रिया या तो बाहर निकलती है, या कॉल निष्पादित नहीं करती है (), जिस बिंदु पर मूल प्रक्रिया जारी है।

इसका मतलब यह है कि एक vfork () की बाल प्रक्रिया को माता-पिता प्रक्रिया के अप्रत्याशित रूप से संशोधित चर से बचने के लिए सावधान रहना चाहिए। विशेष रूप से, बच्चे की प्रक्रिया vfork () कॉल वाले फ़ंक्शन से वापस नहीं आनी चाहिए, और इसे बाहर निकलने की आवश्यकता नहीं है () (अगर इसे बाहर निकलने की आवश्यकता है, तो इसे _exit () का उपयोग करना चाहिए; असल में, यह बच्चे के लिए भी सच है एक सामान्य कांटा ())।

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

Clone : क्लोन, फोर्क के रूप में, एक नई प्रक्रिया बनाता है। कांटा के विपरीत, ये कॉल बच्चे को प्रक्रिया निष्पादन संदर्भ के हिस्सों को कॉलिंग प्रक्रिया के साथ साझा करने की अनुमति देती हैं, जैसे स्मृति स्थान, फ़ाइल वर्णनकर्ताओं की तालिका, और सिग्नल हैंडलर की तालिका।

जब क्लोन के साथ बाल प्रक्रिया बनाई जाती है, तो यह फ़ंक्शन एप्लिकेशन fn (arg) निष्पादित करता है। (यह कांटा से अलग है, जहां मूल फोर्क कॉल के बिंदु से बच्चे में निष्पादन जारी रहता है।) एफएन तर्क एक समारोह के लिए एक सूचक है जिसे बाल निष्पादन की शुरुआत में बाल प्रक्रिया द्वारा बुलाया जाता है। तर्क तर्क एफएन समारोह में पारित किया जाता है।

जब एफएन (तर्क) फ़ंक्शन एप्लिकेशन लौटाता है, तो बच्चे की प्रक्रिया समाप्त हो जाती है। एफएन द्वारा लौटाया गया पूर्णांक बाल प्रक्रिया के लिए निकास कोड है। बच्चे की प्रक्रिया बाहर निकलने (2) या घातक सिग्नल प्राप्त करने के बाद स्पष्ट रूप से समाप्त हो सकती है।

जानकारी प्राप्त हो गई:

इसे पढ़ने का समय निकालने के लिए धन्यवाद ! :)


कांटा () में, या तो बच्चे या अभिभावक प्रक्रिया सीपीयू चयन के आधार पर निष्पादित होगी .. लेकिन vfork () में, निश्चित रूप से बच्चा पहले निष्पादित करेगा। बच्चे को समाप्त करने के बाद, माता-पिता निष्पादित होंगे।


  • execve() निष्पादन योग्य फ़ाइल से लोड किए गए किसी अन्य के साथ वर्तमान निष्पादन योग्य छवि को प्रतिस्थापित करता है।
  • fork() एक बाल प्रक्रिया बनाता है।
  • vfork() का एक ऐतिहासिक अनुकूलित संस्करण है, जिसका उपयोग execve() करने के लिए किया जाता है execve() को fork() बाद सीधे कहा जाता है। यह गैर-एमएमयू सिस्टम में अच्छी तरह से काम करने के लिए निकला (जहां fork() कुशल तरीके से काम नहीं कर सकता) और जब कुछ छोटे प्रोग्राम (जावा के Runtime.exec() ) को चलाने के लिए fork() आईएनजी प्रक्रियाओं को एक विशाल स्मृति पदचिह्न के साथ प्रक्रिया करता है। POSIX ने posix_spawn() बाद के दो और आधुनिक उपयोगों को प्रतिस्थापित करने के लिए posix_spawn() को मानकीकृत किया है।
  • posix_spawn() एक fork()/execve() के बराबर करता है, और इसके बीच कुछ fd juggling को भी अनुमति देता है। यह मुख्य रूप से गैर-एमएमयू प्लेटफार्मों के लिए fork()/execve() को प्रतिस्थापित करना है।
  • pthread_create() एक नया धागा बनाता है।
  • clone() एक लिनक्स-विशिष्ट कॉल है, जिसका उपयोग fork() से pthread_create() तक कुछ भी लागू करने के लिए किया जा सकता है। यह बहुत नियंत्रण देता है। rfork() पर प्रेरित
  • rfork() एक योजना -9 विशिष्ट कॉल है। यह एक सामान्य कॉल माना जाता है, जो पूर्ण प्रक्रियाओं और धागे के बीच साझा करने की कई डिग्री देता है।

  • vfork() एक अप्रचलित अनुकूलन है। अच्छी स्मृति प्रबंधन से पहले, fork() ने माता-पिता की स्मृति की पूरी प्रति बना दी, इसलिए यह बहुत महंगा था। चूंकि कई मामलों में एक fork() बाद exec() , जो वर्तमान मेमोरी मैप को छोड़ देता है और एक नया बनाता है, यह एक आवश्यक व्यय था। आजकल, fork() स्मृति की प्रतिलिपि नहीं करता है; इसे बस "लिखने पर प्रतिलिपि" के रूप में सेट किया गया है, इसलिए fork() + exec() vfork() + exec() vfork() ही कुशल है।

  • clone() fork() द्वारा उपयोग किया जाने वाला सिस्कल है। कुछ मानकों के साथ, यह एक नई प्रक्रिया बनाता है, दूसरों के साथ, यह एक धागा बनाता है। उनके बीच का अंतर सिर्फ डेटा संरचनाओं (मेमोरी स्पेस, प्रोसेसर स्टेट, स्टैक, पीआईडी, ओपन फाइल इत्यादि) साझा या नहीं हैं।