2011-02-23 10 views
5

मुझे प्रोग्राम लिखना है जो pipe() का उपयोग कर प्रक्रिया बनाते हैं।कांटा(), पाइप() और exec() प्रक्रिया निर्माण और संचार

मेरा पहला कार्य एक पेरेंट प्रक्रिया लिखना है जो fork() फ़ंक्शन का उपयोग करके चार बाल प्रक्रियाएं उत्पन्न करता है।

एक बार fork() सफल हो गया है, तो बच्चे की प्रक्रिया को अन्य प्रक्रिया rover1, rover2, rover3, and rover4 के साथ प्रतिस्थापित करें, हालांकि उनमें से सभी एक ही कोड हैं।

प्रक्रियाओं का कार्य निम्नानुसार है।

  1. प्रत्येक बच्चे की प्रक्रिया शुरू में अपना स्वयं का नंबर दिया जाता है। यह माता-पिता से एक नया नंबर प्राप्त करता है। यह इस प्रकार के रूप में अपनी नई संख्या बनाता है और माता-पिता को फ़ॉरवर्ड पर निम्न सूत्र का उपयोग करना:

    mynumber = (3 * mynumber + 4 * numberreceived)/7

  2. यह प्रक्रिया जारी है माता-पिता संदेश यह है कि प्रणाली स्थिर है भेजता है जब तक। माता-पिता का प्रारंभिक संख्या भी है। यह सब बच्चों की संख्या प्राप्त करता है और इस प्रकार अपनी नई संख्या की गणना करता है:

    mynumber = (3 * mynumber + numbers sent by all the children)/7

  3. माता-पिता अपने सभी बच्चों के लिए इस नंबर भेज देंगे। यह प्रक्रिया जारी रहेगी जब तक कि माता-पिता को पता न लगे कि इसकी संख्या अब और नहीं बदली जा रही है। उस समय यह बच्चों को बताएगा कि सिस्टम स्थिर हो गया है।

मैंने यही किया लेकिन मेरे प्रोफेसर ने कहा कि मुझे बच्चे को निष्पादित करने और बच्चे की प्रक्रिया को किसी अन्य बच्चे की प्रक्रिया के साथ बदलने के लिए exec() का उपयोग करना होगा। मुझे यकीन नहीं है कि exec() का उपयोग कैसे करें। क्या आप कृपया इसके साथ मेरी मदद कर सकते हैं।

मैं केवल पहली बाल पीढ़ी को जोड़ रहा हूं।

// I included stdio.h, unistd.h stdlib.h and errno.h 
int main(void) 
{ 
    // Values returned from the four fork() calls 
    pid_t rover1, rover2, rover3, rover4; 

    int parentnumber, mynumber1, mynumber2, mynumber3, mynumber4; 

    int childownnumber1 = 0, status = 1, childownnumber2 = 0, 
     childownnumber3 = 0, childownnumber4 = 0, numberreceived = 0; 

    printf("Enter parent number: "); 
    printf("%d", parentnumber); 
    printf("Enter each children number"); 
    printf("%d %d %d %d", mynumber1, mynumber2, mynumber3, mynumber4); 

    // Create pipes for communication between child and parent 
    int p1[2], p2[2]; 
    // Attempt to open pipe 
    if (pipe(p1) == -1) { 
    perror("pipe call error"); 
    exit(1); 
    } 
    // Attempt to open pipe 
    if (pipe(p2) == -1) { 
    perror("pipe call error"); 
    exit(1); 
    } 

    // Parent process generates 4 child processes 
    rover1 = fork(); 

    // if fork() returns 0, we're in the child process; 
    // call exec() for each child to replace itself with another process 
    if (rover1 == 0) { 
    for(; numberreceived != 1;) { 
     close(p1[1]); // Close write end of pipe 
     close(p2[0]); // Close read end of second pipe 

     // Read parent's number from pipe 
     read(p1[0], &numberreceived, sizeof(int)); 

     if (numberreceived == 1) { 
     // System stable, end child process 
     close(p1[0]); 
     close(p2[1]); 
     _exit(0); // End child process 
     } 

     mynumber1 = (int)((3*mynumber1 + 4*numberreceived)/7.0); 

     printf("\nrover1 number: "); 
     printf("%i", mynumber1); 

     // Write to pipe 
     write(p2[1], &mynumber1, sizeof(int));  
    }  
    } 
    /* Error: 
    * If fork() returns a negative number, an error happened; 
    * output error message 
    */ 
    if (rover1 < 0) { 
    fprintf(stderr, 
      "can't fork, child process 1 not created, error %d\n", 
      errno); 
    exit(EXIT_FAILURE); 
    } 
} 
+0

क्या 'रोवरएक्स' निष्पादन योग्य के भीतर बाल प्रक्रियाओं को करने की कार्यक्षमता है? – user470379

+0

@ user470379- हाँ मुझे लगता है। – cool

उत्तर

2

कार्यों का exec परिवार लिए किया जाता है एक नई प्रक्रिया के साथ मौजूदा प्रक्रिया की जगह। शब्द का उपयोग को प्रतिस्थापित करें। एक बार निष्पादन कहा जाता है, वर्तमान प्रक्रिया चली जाती है और नई प्रक्रिया शुरू होती है। यदि आप एक अलग प्रक्रिया बनाना चाहते हैं, तो आपको पहले fork, और फिर exec बच्चे की प्रक्रिया के भीतर नई बाइनरी अवश्य करनी होगी।

exec फ़ंक्शंस का उपयोग कमांड लाइन से किसी प्रोग्राम को निष्पादित करने के समान है। प्रोग्राम को पास करने के साथ-साथ प्रोग्राम को पास किए गए तर्क exec फ़ंक्शन पर कॉल में प्रदान किए जाते हैं।

उदाहरण के लिए, निम्नलिखित exec आदेश * बाद शेल कमांड के बराबर है:

execl("/bin/ls", "/bin/ls", "-r", "-t", "-l", (char *) 0);

/bin/ls -r -t -l

* ध्यान दें कि "arg0" कमांड/फ़ाइल का नाम है


निष्पादित करने के लिए

चूंकि यह होमवर्क है, इसलिए इस प्रक्रिया की अच्छी समझ होना महत्वपूर्ण है। आप प्रत्येक चरण को बेहतर समझने के लिए pipe, fork, और exec पर कुछ ट्यूटोरियल के साथ संयुक्त रूप से दस्तावेज़ों को पढ़कर शुरू कर सकते हैं।

+0

@ jschmier- उन सभी लिंक के लिए धन्यवाद। मैं ऊपर के रूप में निष्पादन समारोह का उपयोग करेंगे। – cool

1

आप exec का उपयोग करने वाले हैं, तो आप में अपने कार्यक्रम विभाजित करना चाहिए:

निम्न लिंक आप आरंभ करने के लिए मदद करनी चाहिए दो द्विआधारी

असल में, कोड जो अब बच्चे द्वारा निष्पादित किया जाता है, दूसरी बाइनरी में होना चाहिए और इसे exec के साथ बुलाया जाना चाहिए।

exec कार्यों में से किसी एक को कॉल करने से पहले, आपको dup2 का उपयोग करके पाइप डिस्क्रिप्टर को नई प्रक्रिया 'मानक इनपुट/आउटपुट पर रीडायरेक्ट करने की आवश्यकता होगी। इस प्रकार दूसरी बाइनरी में कोड exec 'डी प्राप्त करता है, पाइप से अवगत नहीं होगा और मानक इनपुट/आउटपुट को पढ़/लिख देगा।

यह भी ध्यान देने योग्य है कि बाल प्रक्रिया में अब आप जिस डेटा का उपयोग कर रहे हैं वह माता-पिता से fork के माध्यम से विरासत में मिला है। exec का उपयोग करते समय बच्चा डेटा साझा नहीं करेगा और न ही माता-पिता का कोड, इसलिए हो सकता है कि आप आवश्यक डेटा को पाइप के माध्यम से भी प्रेषित करने पर विचार कर सकें।

+0

मैं अभी यह करूँगा। – cool