2012-06-06 17 views
17

मैं कुछ सी सीखना शुरू कर रहा हूं और कांटा का अध्ययन करते समय, मुझे एक अप्रत्याशित आउटपुट में मिलने वाले कार्यों का इंतजार करना है। कम से कम मेरे लिए।केवल 2 बाल प्रक्रियाओं को बनाने के लिए फोर्क() का उपयोग कैसे करें?

क्या माता-पिता से केवल 2 बाल प्रक्रियाएं बनाने का कोई तरीका है?

यहाँ मेरी कोड:

I'm pid 6763 
I'm pid 6765 
I'm pid 6764 
I'm pid 6766 

कृपया,, पाइप हिस्सा उपेक्षा मुझे लगता है कि अब तक अभी तक नहीं मिला है:

#include <sys/types.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main() 
{ 
    /* Create the pipe */ 
    int fd [2]; 
    pipe(fd); 

    pid_t pid; 
    pid_t pidb; 


    pid = fork(); 
    pidb = fork(); 

    if (pid < 0) 
    { 
     printf ("Fork Failed\n"); 
     return -1; 
    } 
    else if (pid == 0) 
    { 
     //printf("I'm the child\n"); 
    } 
    else 
    { 
     //printf("I'm the parent\n"); 
    } 

    printf("I'm pid %d\n",getpid()); 

    return 0; 
} 

और यहाँ मेरी उत्पादन होता है। मैं केवल 2 बाल प्रक्रियाओं को बनाने की कोशिश कर रहा हूं, इसलिए मुझे उम्मीद है कि 3 "मैं पिड हूं ..." केवल माता-पिता के लिए आउटपुट करता है जो मैं इंतजार करूँगा और 2 बाल प्रक्रियाएं जो पाइप के माध्यम से संवाद करेगी।

मुझे बताएं कि क्या आप देखते हैं कि मेरी त्रुटि कहां है।

+1

'कांटा (2)' दोनों बहुत ही सरल और यूनिक्स एपीआई में सबसे ग़लत समझा कॉल से एक है। बस "संबंधित" साइडबार देखें। क्या कोई विशेष कारण है कि आप दो बच्चों के बीच संचार चाहते हैं, न कि माता-पिता और बच्चे के बीच? – dmckee

+0

फोर्क() कॉल के लिए आप pid == 0 क्यों जांच रहे हैं? मुझे कैसे पता चलेगा कि कौन सा माता पिता है और कौन सा बच्चा है? – TwilightSparkleTheGeek

+1

@TwilightSparkleTheGeek 'man fork' राज्य: वापसी मूल्य सफलता पर, बच्चे की प्रक्रिया का पीआईडी ​​माता-पिता में वापस कर दिया जाता है, और 0 बच्चे में वापस आ जाता है। विफलता पर, -1 माता-पिता में वापस आ गया है, कोई बाल प्रक्रिया नहीं बनाई गई है, और इरनो उचित रूप से सेट है। – mimoralea

उत्तर

30
pid = fork(); #1 
pidb = fork(); #2 

अब दोनों 100 & 101 # 1 के बाद निष्पादन जारी रखने के लिए है, इसलिए वे दूसरे कांटा पर अमल आइए हम मान लेते माता पिता प्रक्रिया आईडी 100 है चलो, पहले कांटा किसी अन्य प्रक्रिया 101. पैदा करता है। पिड 100 एक और प्रक्रिया बनाने के लिए # 2 पहुंचता है 102. पिड 101 # 2 एक और प्रक्रिया बनाने के लिए पहुंचता है 103. तो हम 4 प्रक्रियाओं के साथ खत्म हो जाते हैं।

आपको ऐसा कुछ करना चाहिए।

if(fork()) # parent 
    if(fork()) #parent 
    else # child2 
else #child1 
+3

यह निश्चित रूप से काम करता है। हालांकि, मैं इसके बजाए स्विच स्टेटमेंट का उपयोग करने की सलाह दूंगा। कांटा फ़ंक्शन एक -1 लौटा सकता है और हम इस त्रुटि को एक केस स्टेटमेंट के अंदर -1 के साथ संभाल सकते हैं। – sj755

+0

मैंने सोचा कि माता-पिता अन्य बयान के बाद थे। अगर कथन में माता-पिता क्यों हैं? मैं उलझन में हूं। – TwilightSparkleTheGeek

+1

क्योंकि फोर्क बच्चे पर 0 देता है, माता-पिता नहीं। माता-पिता पर यह आपके द्वारा बनाई गई बाल प्रक्रिया का पीआईडी ​​देता है, जो अधिक उपयोगी है। – mimoralea

3

जब माता-पिता द्वारा कांटा कथन निष्पादित किया जाता है, तो एक बच्चे की प्रक्रिया बनाई जाती है जैसा आप उम्मीद करेंगे। आप कह सकते हैं कि बाल प्रक्रिया भी कांटा कथन निष्पादित करती है लेकिन 0 लौटाती है, माता-पिता, हालांकि, पिड लौटाता है। फोर्क स्टेटमेंट के बाद सभी कोड निष्पादित किया जाता है, माता-पिता और बच्चे को।

आपके मामले में क्या हो रहा था कि पहले कांटा कथन ने एक बाल प्रक्रिया बनाई। तो वर्तमान में एक माता पिता, पी 1, और एक बच्चा, सी 1 है।

अब पी 1 और सी 1 दोनों दूसरे फोर्क स्टेटमेंट का सामना करते हैं। माता-पिता एक और बच्चा (सी 2) बनाता है जैसा आप उम्मीद करेंगे, लेकिन यहां तक ​​कि बच्चा, सी 1 एक बाल प्रक्रिया (सी 3) बनाता है। तो असल में आपके पास पी 1, सी 1, सी 2 और सी 3 है, यही कारण है कि आपको 4 प्रिंट स्टेटमेंट आउटपुट मिलते हैं।

इस बारे में सोचने का एक अच्छा तरीका पेड़ का उपयोग कर रहा है, प्रत्येक नोड एक प्रक्रिया का प्रतिनिधित्व करता है, और रूट नोड शीर्षतम माता-पिता है।

13

प्रक्रिया बनाने के बाद, आपको वापसी मूल्य की जांच करनी चाहिए। यदि आप नहीं करते हैं, तो दूसरा fork() दोनों माता-पिता प्रक्रिया और बाल प्रक्रिया द्वारा निष्पादित किया जाएगा, इसलिए आपके पास चार प्रक्रियाएं हैं।

आप 2 बच्चे प्रक्रियाओं, बस बनाना चाहते हैं:

if (pid = fork()) { 
    if (pid = fork()) { 
     ; 
    } 
} 

आप इस तरह n बच्चे प्रक्रियाओं बना सकते हैं:

for (i = 0; i < n; ++i) { 
    pid = fork(); 
    if (pid) { 
     continue; 
    } else if (pid == 0) { 
     break; 
    } else { 
     printf("fork error\n"); 
     exit(1); 
    } 
} 
0

आप के रूप में मूल्य देख सकते हैं (पीआईडी ​​< 0) प्रक्रिया निर्माण असफल यह बताता है कि क्या बाल प्रक्रिया निर्माण असफल रहा है .. फोर्क बाल प्रक्रिया की प्रक्रिया आईडी लौटाता है अगर getpid() को मूल आय से उपयोग किया जाता है एस एस ..

0

आप एक बच्चे की प्रक्रिया के भीतर एक बाल प्रक्रिया बना सकते हैं। इस तरह आप मूल मूल प्रक्रिया की 2 प्रतियां प्राप्त कर सकते हैं।

int main (void) { 
    pid_t pid, pid2; 
    int status; 

    pid = fork(); 

    if (pid == 0) { //child process 
     pid2 = fork(); 
     int status2; 

     if (pid2 == 0) { //child of child process 
      printf("friends!\n"); 
     } 
     else { 
      printf("my "); 
      fflush(stdout); 
      wait(&status2); 
     } 
    } 
    else { //parent process 
     printf("Hello "); 
     fflush(stdout); 
     wait(&status); 
    } 

    return 0; 
} 

यह प्रिंट निम्नलिखित:

Hello my friends! 
संबंधित मुद्दे