2012-01-13 27 views
7

फोर्क सिस्टम कॉल कोड कैसे लिखा जाता है। मैं कुछ विवरण जानना चाहता हूं कि एक फ़ंक्शन दो अलग-अलग मानों को कैसे वापस कर सकता है और दो अलग-अलग प्रक्रियाओं में। संक्षेप में जानना चाहते हैं कि फोर्क सिस्टम कॉल कैसे कार्यान्वित किया जाता है?फोर्क कार्यान्वयन

+3

आप लिनक्स कर्नेल स्रोत कोड को आजमा सकते हैं और देख सकते हैं ... – fge

+1

क्या आप इस विचार से सहज हैं कि ओएस प्रक्रियाएं बना सकता है, और प्रत्येक प्रक्रिया के पता स्थान पर मैप करने के लिए स्मृति के कौन से क्षेत्र चुन सकते हैं? –

+0

इस सवाल का क्या मतलब है? – Svisstack

उत्तर

9

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

  1. कार्यक्रम कॉल fork() सिस्टम कॉल
  2. कर्नेल कांटा सिस्टम कॉल प्रक्रिया डुप्लिकेट कार्यक्रम
  3. गिरी सेट मूल कार्यक्रम के लिए और डुप्लिकेट के लिए सिस्टम कॉल के लिए वापसी मान चल (पीआईडी ​​की डुप्लिकेट और 0, क्रमशः)
  4. कर्नेल दोनों प्रक्रियाओं को रखता है शेड्यूलर कतार
  5. प्रत्येक प्रक्रिया निर्धारित होने के बाद, कर्नेल 'दो' कार्यक्रमों में से प्रत्येक को 'रिटर्न' देता है।

    return pid; 
    return 0; 
    

    पहले प्रक्रिया पहले निष्पादित करेंगे:

-1

उदाहरण प्रक्रिया के लिए आसान तरीका में आईपी/EIP/आरआईपी चलती रजिस्टर कि तरह दिख सकता है कार्यों में कुछ निर्देश को छोड़ने के लिए साथ fork() समारोह में क्लोन है स्टैक से निर्देश और पॉप फ़ंक्शन, दूसरी प्रक्रिया शुरू हो जाएगी, लेकिन दूसरे निर्देश से 0

+0

मुझे लगता है कि यह सिर्फ कर्नेल है जो प्रत्येक प्रक्रिया के लिए सिस्टम कॉल से विभिन्न मान लौटा रहा है। – tangrs

+0

जब आप फोर्क() कहते हैं तो उसी प्रक्रिया से दोनों प्रक्रिया कांटा। मुझे नहीं पता कि "दूसरी" प्रक्रिया (माता-पिता या बच्चे) से आपका क्या मतलब है, लेकिन यह गलत है – iantonuk

2

Unix V6 विश्वविद्यालय कोड के लिए स्रोत कोड पुस्तिका में एक टिप्पणी है जिसे केन थॉम्प द्वारा एनोटेट किया गया था ऑन और डेनिस रिची स्वयं वर्णन करते हैं कि डबल रिटर्न वास्तव में कैसे काम करता है। टिप्पणी निम्नलिखित वाक्य के साथ समाप्त होती है:

आपको यह समझने की उम्मीद नहीं है।

+0

आईआईआरसी जो इसके लिए उपयोग की गई असेंबली को संदर्भित करता है, न कि दो बार लौटने के विचार के लिए। – ninjalj

7

कार्ल का जवाब बहुत अच्छा था। मैं यह जोड़ना चाहता हूं कि कई ऑपरेटिंग सिस्टम में रिटर्न मूल्य रजिस्टरों में से एक में पास हो जाते हैं। X86 आर्किटेक्चर में यह रजिस्टर ईएक्स हो सकता है, एआरएम आर्किटेक्चर में यह रजिस्टर आर 0, आदि हो सकता है।

प्रत्येक प्रक्रिया में प्रोसेस कंट्रोल ब्लॉक (पीसीबी) भी होता है, जो कुछ इंटरप्ट, सिस्कल या उस समय रजिस्टरों के मूल्यों को स्टोर करता है। अपवाद हुआ और ओएस को नियंत्रण पारित किया गया था। अगली बार प्रक्रिया निर्धारित होने पर, रजिस्टरों के मूल्य पीसीबी से बहाल किए जाते हैं।

अब, जब कांटा() होता है, ओएस कर सकते हैं:

child_process->PCB[return_value_register] = 0; 
parrent_process->PCB[return_value_register] = child_pid; 

तो, जब प्रक्रियाओं पुनर्निर्धारित कर रहे हैं, उनमें से प्रत्येक एक अलग वापसी मान देखें।

उदाहरण के तौर पर, आप xv6's implementation of fork देख सकते हैं। वहां, मूल प्रक्रिया अभी भी चल रही स्थिति में है, इसलिए यह सरल वापसी कथन का उपयोग करके माता-पिता के वापसी मूल्य को वापस कर देता है। लेकिन यह 0 के लिए बच्चे की प्रक्रिया के लिए EAX रजिस्टर का मूल्य निर्धारित करता है, इसलिए जब बच्चे प्रक्रिया निर्धारित है यह वापसी मान के रूप में 0 देखता है:

// Clear %eax so that fork returns 0 in the child. 
np->tf->eax = 0; 

ध्यान दें कि वापसी 0 भी तरह "mov eax, 0" कुछ करने के लिए संकलित कर देगा।

अद्यतन: मैंने अभी एक शौक ओएस के लिए फोर्क() लागू किया है। आप स्रोत कोड here देख सकते हैं।

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