2015-09-29 5 views
5

हाय वहाँ मैं ऐसे कार्यक्रम पर काम कर रहा हूं जो बच्चों को फेंक देगा और बाद में प्रत्येक बच्चे से अधिक बच्चों को फेंक देगा लेकिन मुझे वह मदद नहीं चाहिए जो मुझे चाहिए साथ में। जब मैं अपना प्रोग्राम चलाता हूं (यहां पर यह एक फ़ंक्शन है लेकिन वही काम करता है) मुझे लगता है कि एक माता-पिता (पीपीआईडी) स्पॉन 3 बच्चे (पीआईडीएस = 1,2,3) होना चाहिए लेकिन मुझे जो मिलता है वह एक ही पीआईडी ​​और पीपीआईडी ​​है 3 बार (मेरा वर्तमान कोड) या इससे पहले कि मैं प्रत्येक माता-पिता के साथ 3 माता-पिता प्राप्त कर रहा था, जिसमें एक बच्चा था और पीपीआईडीएस अलग-अलग पीआईडीएस थे, लेकिन पीपीआईडी ​​पिछले बच्चे पीआईडी ​​के समान ही थे। मेरे नवीनतम प्रयासों में यह कभी बच्चे (बेटे) के ऊपर माता-पिता (पिता) संदेश प्रदर्शित नहीं करता है। यह इस तरह दिखना चाहिएफोर्क() का उपयोग करके 1 बच्चों में से 1 बच्चे (सी ++ नहीं)

[dad] hi am I PID 1234 and I come from ####(dont care what this number is) 
[son] hi i am PID 1111 and I come from PPID 1234 
[son] hi i am PID 1112 and I come from PPID 1234 
[son] hi i am PID 1113 and I come from PPID 1234 

यहां मेरा कोड है। यदि संभव हो तो मैं सिर्फ संकेतों की तलाश कर रहा हूं जब तक कि यह सिर्फ एक मूर्खतापूर्ण गलती नहीं है जैसा मैंने किया है "ओह बस बच्चे की प्रक्रिया में कांटा() को ले जाएं" या ऐसा कुछ।

इसके अलावा मेरे पास एक बच्चा है इसलिए मैं आसानी से बच्चों की गिनती कर सकता हूं।

int forking(null) 
{ 
     void about(char *); 
     int i=0; 
     int j=0; 
     int child_count =0; 
     about("dad"); 

    for(i = 0; i < 3; i++){ 
     pid_t child = 0; 
     child = fork(); 


      if (child < 0) { //unable to fork error 
        perror ("Unable to fork"); 
        exit(-1);} 

      else if (child == 0){ //child process 
        about ("son"); 
        printf("I am child #%d \n",child_count); 
        child_count++; 
        exit(0);} 

      else { //parent process (do nothing) 

       } 
      } 

       for(j = 0; j < 3; j++){ 
          wait(NULL);//wait for parent to acknowledge child process 
          } 
return 0; 
} 
+3

दो बातें याद करने के लिए: पहला यह है कि एक बार आप अलग किया गया है, बच्चे प्रक्रिया माता पिता की स्मृति की एक प्रति प्राप्त है, और जब बच्चे जैसे को संशोधित करता है परिवर्तनीय वे चर केवल बच्चे में बदल जाते हैं, माता-पिता (या किसी भी "भाई बहन") उन परिवर्तनीय परिवर्तनों को नहीं देख पाएंगे। दूसरी बात यह है कि आप 'else' में 'प्रतीक्षा' पर कॉल करते हैं, दोनों माता-पिता * और * बच्चे को अवरुद्ध करेंगे। –

+3

ओह, और आपके कोड में * अपरिभाषित व्यवहार * का एक बुरा मामला है। आप 'child' चर परिभाषित करते हैं, लेकिन फिर आप इसका उपयोग * पहले * करते हैं। अनियंत्रित स्थानीय चर के पास * अनिश्चित * मान होता है, प्रारंभिक किए बिना उनका उपयोग यूबी की ओर जाता है। आप इस बारे में सोचना चाहेंगे कि आप कहां 'फोर्क' कहलाते हैं। –

+0

ओह तुम्हारा मतलब है pid_t child = 0? आपका क्या मतलब है() माता-पिता और बच्चे दोनों को अवरुद्ध करता है? और स्मृति की प्रति के बारे में क्या आप मुझे एक उदाहरण कोड दे सकते हैं? यह उस बिंदु को देखना आसान बनाता है। – Jite

उत्तर

4

माता पिता
करने की जरूरत है - संदेश
प्रिंट - फोन कांटा तीन बार
- इंतजार तीन बच्चों

प्रत्येक बच्चे
करने की जरूरत है बाहर निकलने के लिए के लिए - संदेश मुद्रित
- बाहर निकलें

तो कोड

int main(void) 
{ 
    printf("[dad] pid %d\n", getpid()); 

    for (int i = 0; i < 3; i++) 
     if (fork() == 0) 
     { 
      printf("[son] pid %d from pid %d\n", getpid(), getppid()); 
      exit(0); 
     } 

    for (int i = 0; i < 3; i++) 
     wait(NULL); 
} 
012 जितना आसान है

जो इस उत्पादन

[dad] pid 1777 
[son] pid 1778 from pid 1777 
[son] pid 1779 from pid 1777 
[son] pid 1780 from pid 1777 
उत्पन्न
+0

को अपडेट किया जा सकता है। यह कैसा है? – Jite

2

एक बात आपको याद है कि, जब आप fork, दोनों माता पिता और बच्चे के उस बिंदु पर कोड चलाने पर जारी रहेगी।

तो, यदि आप बच्चे/माता-पिता का पता लगाने से सही तरीके से काम नहीं करते हैं, तो बच्चे शायद अपने बच्चों को शुरू कर देंगे।

आप तीन बच्चों को शुरू करने के लिए और कोई पोते एक काउंटर, fork कॉल से लौटे प्रक्रिया ID साथ संयोजन के रूप में उपयोग करने के लिए निम्नलिखित की तर्ज पर है के लिए एक अच्छा तरीका:

#include <stdio.h> 
#include <unistd.h> 

#define COUNT 3 

int main(void) { 
    # Desired and actual count. 

    int count = COUNT, children = 0; 

    // Force parent initially. 

    pid_t retpid = 1; 

    // Only fork if limit not reached AND is parent (children 
    // will exit loop with retpid == 0). 

    while (count-- > 0 && retpid > 0) 
     // Adjust actual count if successful. 

     if ((retpid = fork()) > 0) 
      children++; 

    // Detect parent, all forks returned non-zero. 

    if (retpid != 0) { 
     printf("Parent %d spawned %d/%d children\n", 
      getpid(), children, COUNT); 

     // Wait for children to finish. 

     while (children-- > 0) 
      wait(NULL); 
    } else { 
     // Otherwise you were one of the children. 

     printf("Child %d, sired by %d\n", getpid(), getppid()); 
    } 

    return 0; 
} 

यह आउटपुट क्या आप, हालांकि बाद होने लगते हैं शेड्यूलिंग की अनियमितता, इसी क्रम में जरूरी नहीं कि के कारण: केवल माता-पिता करता सुनिश्चित करेगा

Parent 26210 successfully spawned 3/3 children 
Child 26212, sired by 26210 
Child 26213, sired by 26210 
Child 26211, sired by 26210 

लौटे पीआईडी ​​की जाँच किसी भी फोर्किंग, और गिनती इसे एक विशिष्ट मात्रा तक सीमित कर देगी।


एक चीज जिसे आप आउटपुट बफरिंग के लिए भी देखना चाहते हैं। जब आप कांटा करते हैं, तो आप buffered आउटपुट डेटा के साथ दो प्रक्रियाओं के साथ समाप्त हो सकते हैं।

जहां आउटपुट डिवाइस टर्मिनल होने के लिए पता लगाया जा सकता है, फ्लशिंग सामान्य रूप से आउटपुट होने पर एक नई लाइन पर होती है, इसलिए आपके printf कॉल सामान्य रूप से सामान्य रन के लिए आउटपुट डुप्लिकेट नहीं करेंगे।

आपको केवल यह पता होना चाहिए कि आपको दिलचस्प परिणाम मिल सकते हैं यदि आप अपने आउटपुट को फ़ाइल में रीडायरेक्ट करते हैं, उदाहरण के लिए।

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