2013-06-01 8 views
6

में कांटा() मैं दो बच्चे प्रक्रियाओं बनाने के लिए की जरूरत है। एक बच्चा आदेश "ls -al" चलाने के लिए और अगले बच्चे प्रक्रिया के इनपुट, जो बारी में आदेश "प्रकार -r -k 5 -n" अपने इनपुट डेटा पर चलेगा करने के लिए इसके उत्पादन रीडायरेक्ट करने के लिए की जरूरत है। अंत में, मूल प्रक्रिया को पढ़ने की आवश्यकता है (डेटा पहले ही सॉर्ट किया गया है) और इसे टर्मिनल में प्रदर्शित करें। के रूप में अगर मैं खोल में सीधे निम्न आदेश में प्रवेश किया टर्मिनल में अंतिम परिणाम (जब कार्यक्रम को क्रियान्वित करने) एक ही होना चाहिए: "ls -al | तरह -r -k 5 -n"। इसके लिए मुझे निम्न विधियों का उपयोग करने की आवश्यकता है: पाइप(), कांटा(), execlp()।पाइप() और ग

मेरा प्रोग्राम संकलित करता है, लेकिन मुझे टर्मिनल पर वांछित आउटपुट नहीं मिलता है। मुझे नहीं पता कि क्या गलत है।

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

int main() 
{ 
    int fd[2]; 
    pid_t ls_pid, sort_pid; 
    char buff[1000]; 

    /* create the pipe */ 
    if (pipe(fd) == -1) { 
     fprintf(stderr, "Pipe failed"); 
     return 1; 
    } 

    /* create child 2 first */ 
    sort_pid = fork(); 
    if (sort_pid < 0) {       // error creating Child 2 process 
     fprintf(stderr, "\nChild 2 Fork failed"); 
     return 1; 
    } 
    else if(sort_pid > 0) {      // parent process 

     wait(NULL);        // wait for children termination 

     /* create child 1 */ 
     ls_pid = fork(); 
     if (ls_pid < 0) {      // error creating Child 1 process 
      fprintf(stderr, "\nChild 1 Fork failed"); 
      return 1; 
     } 
     else if (ls_pid == 0) {     // child 1 process 
      close(1);       // close stdout 
      dup2(fd[1], 1);      // make stdout same as fd[1] 
      close(fd[0]);      // we don't need this end of pipe 
      execlp("bin/ls", "ls", "-al", NULL);// executes ls command 
     } 

     wait(NULL); 
     read(fd[0], buff, 1000);    // parent reads data 
     printf(buff);       // parent prints data to terminal 
    } 
    else if (sort_pid == 0) {     // child 2 process 
     close(0);        // close stdin 
     dup2(fd[0], 0);       // make stdin same as fd[0] 
     close(fd[1]);       // we don't need this end of pipe 
     execlp("bin/sort", "sort", "-r", "-n", "-k", "5", NULL); // executes sort operation 
    } 

    return 0; 
} 
+5

जब तक अगर आप से क्रियान्वित कर रहे हैं '/', "/ bin/ls" से "bin/ls" की जगह की कोशिश (के लिए इसी तरह की "/ bin/तरह") – wildplasser

+0

ऐसा लगता है कि कोई त्रुटि जाँच कर रहे हैं। आपको कुछ जोड़ना चाहिए, जो आपको इस मुद्दे का निदान करने में मदद करेगा। –

+0

मेरे पास बच्चों के ब्लॉक के अंदर printf() कथन हैं। "/" के बिना, यह मुझे बच्चों के बयान दोनों दिखाता है लेकिन जब मैं "/" डालता हूं तो यह उन बयानों को नहीं दिखाता है; ऐसा लगता है कि यह बच्चों के ब्लॉक तक नहीं पहुंचता है। – user2443819

उत्तर

3

आपके अभिभावक प्रक्रिया तरह की प्रक्रिया के लिए wait रों ls प्रक्रिया बनाने से पहले खत्म करने के लिए: यहाँ कोड है।

सॉर्ट प्रक्रिया को समाप्त होने से पहले इसके इनपुट को पढ़ने की आवश्यकता है। और इसका इनपुट एलएस से आ रहा है जो wait के बाद तक शुरू नहीं किया जाएगा। गतिरोध।

आपको दोनों प्रक्रियाओं को बनाने की आवश्यकता है, फिर wait दोनों के लिए।

इसके अलावा, आपकी फ़ाइल डिस्क्रिप्टर मैनिपुलेशन बिल्कुल सही नहीं है। कॉल की इस जोड़ी में:

close(0); 
dup2(fd[0], 0); 

बंद करना अनावश्यक है, क्योंकि डुप्ली 2 स्वचालित रूप से मौजूदा एफडी 0 को बंद कर देगा यदि कोई है। आपको थ्रू 2 के बाद close(fd[0]) करना चाहिए, इसलिए आपके पास पाइप के उस छोर से केवल एक फ़ाइल डिस्क्रिप्टर है। और अगर आप वास्तव में मजबूत होना चाहते हैं, तो आप पहले से ही fd[0]==0 सूख परीक्षण करना चाहिए, और उस मामले में dup2 और करीबी को छोड़ दें।

अन्य dup2 भी करने के लिए यह सब लागू करें।

तब पाइप को खोलने वाली मूल प्रक्रिया का मुद्दा खुला है। मैं कहूंगा कि आपको बच्चों को पारित करने के बाद माता-पिता में पाइप के दोनों सिरों को बंद करना चाहिए, लेकिन पिछले wait के बाद fd[0] से आपके पास अजीब read है ... मुझे यकीन नहीं है कि वह क्यों है। यदि ls|sort पाइपलाइन सही ढंग से चलती है, तो पाइप बाद में खाली हो जाएगी, इसलिए पढ़ने के लिए कुछ भी नहीं होगा। किसी भी मामले में, आप निश्चित रूप से माता-पिता में fd[1] बंद करने के लिए, अन्यथा तरह प्रक्रिया को समाप्त नहीं होगा, क्योंकि पाइप EOF का संकेत नहीं होगा जब तक सभी लेखकों बंद हो जाती हैं की जरूरत है।

अजीब read एक printf है जो शायद क्रैश हो जाएगा, क्योंकि पढ़ा बफर '\0' -टाइमेटेड नहीं होगा।

और execlp का उपयोग करने का बिंदु यह है कि यह आपके लिए $PATH लुकअप करता है ताकि आपको /bin/ निर्दिष्ट करने की आवश्यकता न हो। मेरा पहला टेस्ट रन विफल हुआ क्योंकि मेरा सॉर्ट /usr/bin/ में है। हार्डकोड पथ क्यों हैं जब आपको नहीं करना है?

+0

आपको बहुत बहुत धन्यवाद; मुझे अब यह काम मिल गया। मैंने डुप् 2 के पहले अनावश्यक बंद कर लिया; मैंने आखिरी प्रतीक्षा() के बाद डीएफ [0] से पढ़ा() भी निकाला। मुझे एहसास हुआ कि यह जरूरी नहीं है। मैंने सॉर्ट ब्लॉक के अंदर एक खुला (1) कथन जोड़ा ताकि टर्मिनल में सॉर्ट का आउटपुट प्रदर्शित हो सके, और आखिरकार मैंने बफ वैरिएबल को पूरी तरह से बाहर निकाला और आखिरी प्रिंटफ की आवश्यकता नहीं है क्योंकि उनकी आवश्यकता नहीं है। – user2443819

+0

ओह !, और मैं केवल बच्चों की प्रक्रियाओं के बाद प्रतीक्षा (एनयूएलएल) करता हूं। – user2443819

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