2012-03-15 7 views
5

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

#include<stdio.h> 
int i=10; 
int pid; 
int main(){ 
    if((pid=fork())==0){ 
    i++;//somewhere I read that separate memory space for child is created when write is needed 
    printf("parent address= %p\n",&i);// this should return the address from parent's memory space 
    }else{ 
    i++; 
    i++; 
    printf("child address= %p\n",&i);// this should return the address of child's memory space 
    } 
    wait(0); 
    return(0); 
} 
 
Why The output looks like:: 
child address::804a01c 
parent address::804a01c 

क्यों दोनों पते माता-पिता के साथ ही बच्चे के लिए ही कर रहे हैं?

+4

वे * बेहतर * समान थे। आप पॉइंटर्स को दोनों प्रक्रियाओं में स्मृति को संदर्भित करना चाहते हैं (भले ही दोनों मेमोरी भाग अलग हैं)। * वर्चुअल मेमोरी * के बारे में पढ़ें, यह आपके प्रश्न का उत्तर देगा। –

+1

ध्यान दें कि 'i' के * मान * माता-पिता और बच्चे के बीच अलग हैं, भले ही दोनों प्रतियां समान वर्चुअल पते पर संग्रहीत हों। – markgz

उत्तर

8

उनके वर्रों और कार्यों को सौंपा गया दो अलग-अलग मेमोरी स्थान हैं।

नहीं; लिनक्स virtual memory लागू करता है, जिसका अर्थ है कि प्रत्येक प्रक्रिया का अपना पूरा पता स्थान होता है। नतीजतन, fork के बाद, दोनों प्रक्रियाएं इन-मेमोरी ऑब्जेक्ट्स की प्रतियों के लिए समान पते देखती हैं।

:

+4

वास्तव में "अलग" वास्तव में महत्वपूर्ण है: जब बच्चे की प्रक्रिया उत्पन्न होती है तो वास्तव में कुछ भी कॉपी नहीं किया जाता है। यह एक बड़ा प्रदर्शन नुकसान होगा, यह देखते हुए कि यूनिक्स पर फोर्किंग अक्सर होती है (वस्तुतः हर बार जब आप एक नई प्रक्रिया उत्पन्न करते हैं)। सटीक तंत्र "पृष्ठ दोष" पर निर्भर करता है। यदि आप रुचि रखते हैं तो आप उनके बारे में पढ़ना चाहेंगे। –

+0

ठीक है, तो हम उस var का वास्तविक पता कैसे प्राप्त कर सकते हैं और आभासी नहीं? (केवल मेरी जिज्ञासा को पूरा करने के लिए कह रहे हैं) – buch11

+1

@ buch11: मुझे लगता है कि आप नहीं कर सकते, लेकिन मैं विशेषज्ञों की पुष्टि करूंगा। वैसे भी, आपको नहीं करना चाहिए। इस तरह की जानकारी केवल कर्नेल द्वारा जानी जाती है, और यह केवल आपको स्थानीय पते की प्रक्रिया तक पहुंचने देगी। इसे "संरक्षित स्मृति" के रूप में जाना जाता है। प्रत्येक प्रक्रिया केवल अपनी याददाश्त तक पहुंच सकती है। –

2

पतों प्रक्रिया-स्थानीय कर रहे हैं (एक अलग रूप में के रूप में वी एम भी कारण बनता है कोड भौतिक स्मृति में प्रक्रिया के बीच साझा करने, और सभी डेटा केवल copied-on-write हो जाएगा।)। एक प्रक्रिया में 804a01c किसी अन्य प्रक्रिया में 804a01c जैसा नहीं है।

2

virtual memory की वजह से: दोनों पता स्थान संबंधित प्रक्रियाओं के समान दिखते हैं। उन भौतिक मेमोरी में संग्रहीत हैं जो अलग हैं। हालांकि, व्यावहारिक रूप से, एक मेमोरी ऑप्टिमाइज़ेशन (अधिकांश कर्नल द्वारा कार्यान्वित) द्वारा जटिल है जो समान भौतिक पृष्ठों के अनुरूप विभिन्न वर्चुअल पृष्ठों को मानचित्र करता है जब तक कि उन प्रक्रियाओं में से कोई एक स्मृति के उस पृष्ठ पर लिखता है, उस समय पृष्ठ को भौतिक रूप से डुप्लिकेट किया जाता है किसी अन्य भौतिक पते पर (और वर्चुअल पेज को प्रक्रिया के लिए रीमेप किया गया है)।

कई अन्य जटिलताओं भी हैं: सबसे अधिक मान्यता प्राप्त है कि fork() का वापसी मूल्य प्रक्रियाओं के बीच भिन्न होता है, हालांकि यह आमतौर पर एक रजिस्टर मान में अंतर होता है, स्मृति नहीं। हालांकि, खुली फ़ाइलें, और कुछ अन्य संसाधनों को विरासत में चिह्नित किया जा सकता है, इसलिए अन्य अंतर — मामूली लेकिन कभी-कभी उपयोगी हो सकते हैं।

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