2016-11-04 11 views
5

मैं दो कार्यक्रमों उनमें से एक जनरेटर नामित जो कुछ पाठ मुद्रित हर दूसरेग stdout stdin के लिए वास्तविक समय

int main(int argc, char** argv) { 

    for(int i = 0; i < 10 ; i++) { 
     printf("something\n"); 
     sleep(1); 
    } 

    return (EXIT_SUCCESS); 
} 

तो एक एक दूसरे कार्यक्रम यह उपभोक्ता फोन अब के लिए है, जो एक standart इनपुट से पढ़ना चाहिए है बनाते हैं इसे किसी अन्य पाठ में जोड़ें और इसे पुनः मुद्रित करें। इसे इस तरह देखें:

int main(int argc, char** argv) { 


    char line[BUFSIZ]; 

    while(scanf("%s",line) != -1){ 
     printf("you entered %s \n",line); 
    } 

    return (EXIT_SUCCESS); 
} 

जब मैं उन्हें संकलन और जैसे ही एक जनरेटर चलाने का प्रयास ./generator यह के रूप में मैं उम्मीद काम करता है। हर दूसरे कुछ कंसोल पर प्रिंट है। लेकिन जब मैं उन्हें दोनों को चलाने की कोशिश करता हूं ./generator | ./consumer जैसा कि मैंने अपेक्षा की थी, यह काम नहीं करता था। मैं 10 सेकेंड का इंतजार करता हूं और उसके बाद की 10 लाइनें प्राप्त करती हैं, आपने कुछ दर्ज किया है, मैं हर सेकेंड में "आपने कुछ दर्ज किया" प्रिंट करना चाहता हूं।

क्या आप मुझे समझा सकते हैं कि ऐसा क्यों है, या बेहतर टेलि मुझे उम्मीद है कि अपेक्षित व्यवहार कैसे प्राप्त किया जाए?

उत्तर

3

आपके printf से आउटपुट buffered किया जा रहा है, और केवल बफर भरने पर बाहर आ रहा है। आप स्टूडआउट पर नल पर बफर आकार सेट करने के लिए, दूसरे तर्क के रूप में उपभोक्ता (सेट में एक बार) में setbuf() को कॉल कर सकते हैं।

#include <stdio.h> 
setbuf(stdout, NULL); 

इससे आउटपुट को तुरंत बाहर आने के लिए stdout (यानी आपका printf) लिखा गया हो जाएगा। वैकल्पिक रूप से आप stderr को लिख सकते हैं, जो डिफ़ॉल्ट रूप से एक पूर्ण बफर आकार होता है। (या, एक और विकल्प के रूप में, जब भी आप टर्मिनल पर बफर सामग्री को फ्लश करना चाहते हैं तो आप stdout पर fflush को कॉल कर सकते हैं)।

+1

या आप का उपयोग कर stdbuf -o0 ./generator कमांड लाइन पर बफरिंग बंद कर सकते हैं | ।/ उपभोक्ता –

+0

@RomanHocke प्रतीक्षा करें एक प्रोग्राम मौजूद है जो उपयोगकर्ता मोड व्यवहार को किसी अन्य प्रक्रिया के पूर्व-निष्पादन के लिए बदल देता है? वैसे यह दिलचस्प है ... –

2

आउटपुट buffered है, इसलिए stdio लाइब्रेरी तब तक प्रतीक्षा करता है जब तक कि इसमें डेटा का गुच्छा न हो, आमतौर पर 4 किलोबाइट्स, और फिर इसे एक साथ आउटपुट करता है।

बस जब भी आप उत्पादन वास्तव में उत्पादन होना चाहता हूँ fflush के लिए एक कॉल जोड़ें:

fflush(stdout); 

यह अलग ढंग से काम करता है जब उत्पादन टर्मिनल के लिए सीधे भेजा जाता है। मानक आउटपुट तब लाइन buffered है, तो बफर प्रत्येक अंतराल के चरित्र के बाद flushed है।

4

सी आई/ओएस buffered हैं। टर्मिनल I/Os का उपयोग करते समय, बफरिंग अनुशासन लाइन बफर किया गया है, इसलिए \n भेजे जाने पर सामग्री को आउटपुट में फ़्लश किया जाता है। जब आप पाइप का उपयोग करते हैं, तो बफरिंग अनुशासन पूर्ण buffered है ताकि बफर भरने पर सामग्री केवल तभी फ़्लश हो (जो भी सामग्री हो)।

आप या तो:

  1. flush(stdout) हर बार जब आप की जरूरत है वास्तव में बाहर लिखा जा करने के लिए डेटा,
  2. परिवर्तन setvbuf के लिए एक कॉल किसी भी लिखने से पहले से बफर अनुशासन।
-3

आप अपने कार्यक्रम समानांतर के कुछ हिस्सों को निष्पादित करने के धागे का उपयोग करना चाहिए:

#include <iostream> 
#include <thread> 
#include <unistd.h> 

using namespace std; 
void Print() { 


sleep(1); 
cout << "Thread trolling you!!!\n"; 
Print(); 
} 

int main() { 
string g; 
thread ttt(Print); //create thread, from now Print() runs parallel to 
cin >> g;   //the rest of int main() 
cout << g; 
ttt.join();   //join threads 
return (0); 
} 
+0

सिर्फ एक उदाहरण है जो आपकी समस्या का सीधा समाधान नहीं है। – Legolas

+1

सीमित अधिकतम गहराई के बिना रिकर्सिव फ़ंक्शन? मुझे नहीं लगता कि सी ++ ने पूंछ कॉल ऑप्टिमाइज़ेशन की गारंटी दी है, तो यह थोडा है ... बुरा। – hyde

+0

यह भी जवाब इस सवाल को बहुत बुरा लगता है ... – hyde

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