2016-10-24 7 views
10

मैं एक फोर्क प्रक्रिया के STDOUT से पढ़ने की कोशिश कर रहा था। हालांकि, अगर मैं एक अनंत for loop में पाइप से पढ़ रहा हूं, तो यह प्रतीक्षा में व्यस्त रहेगा कि पाइप के माध्यम से कोई डेटा नहीं आ रहा है (अगर मैं गलत हूं तो कृपया मुझे सही करें), और मुझे लगता है कि ऐसा करने का एक बेहतर तरीका होना चाहिए sleep का उपयोग करने के अलावा यदि यह छोटी अंतराल के लिए है, तो कॉलबैक के साथ हो सकता है, जिसके बारे में मुझे यकीन नहीं है। नीचे कोड स्निपेट है जो मैंने कोशिश की थी।सी में, क्या हम बिना व्यस्त किए पाइप से पढ़ सकते हैं, कॉलबैक या अन्य तरीकों का उपयोग कर सकते हैं?

pid_t pid = fork(); 
switch (pid) { 
    case 0: 
     dup2 (pipes[1], STDOUT_FILENO); 
     dup2(pipes[1], STDERR_FILENO); 
     close(pipes[0]); 
     close(pipes[1]); 
     execv(path, args); 
     break; 
    default : 
     close(STDIN_FILENO); 
     close(STDOUT_FILENO); 
     close(STDERR_FILENO); 
     child_pid = pid; 
     signal(SIGHUP, mysighandle); 
     close(pipes[1]); 
     ssize_t nbytes; 
     for (;;) { 
      nbytes = read(pipes[0], buf, BUFSIZE); 
      if (nbytes == -1){ 
       break; 
      } 
      if (nbytes == 0) { 
       break; 
      } 
      syslog(LOG_NOTICE, "%s", buf); 

क्या कोई व्यस्तता के बिना बेहतर तरीका सुझा सकता है, जिसका उपयोग पाइप से डेटा पढ़ने के लिए किया जा सकता है? चूंकि मैं C में एक नौसिखिया हूं, कोड-स्निपेट के किसी भी संदर्भ की सराहना की जाती है।

सम्मान।

+6

यदि आप गैर-अवरुद्ध मोड में फ़ाइल डिस्क्रिप्टर सेट नहीं करते हैं, तो डिफ़ॉल्ट रूप से 'read() 's अवरुद्ध कर रहे हैं - यानी यदि वे डेटा उपलब्ध होने तक ब्लॉक करते हैं - तो वहां कोई व्यस्त प्रतीक्षा नहीं है। –

उत्तर

9

अपने कोड में, आप non-blocking mode करने के लिए अपने पाइप सेट नहीं किया है (कम से कम, मुझे लगता है आप, नहीं है के बाद से आप वास्तव में नहीं दिखा आप इसे कैसे खोल रहे हैं), और इसलिए read() कर रही है एक अवरुद्ध पढ़ा। यही है, यदि कोई डेटा उपलब्ध नहीं है, लेकिन कुछ प्रक्रिया में अभी भी पाइप लिखने के लिए खुला है, तो यह स्वचालित रूप से आपकी प्रक्रिया को तब तक रोक देगा जब तक कि अधिक डेटा उपलब्ध न हो (और तब उस डेटा को बफर में पढ़ा जाएगा)।

इस प्रकार, आपका कोड ठीक उसी तरह काम करता है जैसा कि यह है, और इसे बदलने की कोई आवश्यकता नहीं है।

(यानी, जब तक आप एक ही समय में एकाधिक पाइप से पढ़ना नहीं चाहते हैं, या उसी धागे में कुछ और करने के दौरान डेटा की प्रतीक्षा करना चाहते हैं, तो इस मामले में आपको वास्तव में select() और (संभवतः) गैर-अवरोधन का उपयोग करना चाहिए I/O।)

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