2012-05-22 29 views
6

मैं fork() और पुनः दिशा के साथ प्रयोग किया गया था जांच करने के लिए है कि क्या फिर से दिशाओं माता-पिता में किया भी बच्चे के लिए लागू होते हैं। मैं निम्नलिखित साधारण प्रोग्रामवक्तव्य() मुद्रण दो बार

#include<stdio.h> 
#include<unistd.h> 
#include<stdlib.h> 

int main() 
{ 
    freopen("error.txt", "w+t", stdout); // From now on, stdout = error.txt 
    printf (" ERROR! WHY DONT U UNDERSTAND?\n"); 
    if (fork() == 0) 
    { 
     printf(" I AM CHILD\n"); 
     exit(0); 
    } 
    else- 
    { 
     printf (" EITHER I AM A PARENT OR SOMETHING GOT SCREWED\n"); 
    } 


    return 0; 
} 

निर्गम (error.txt) मुझे मिल गया

ERROR! WHY DONT U UNDERSTAND? 
EITHER I AM A PARENT OR SOMETHING GOT SCREWED 
ERROR! WHY DONT U UNDERSTAND? 
I AM CHILD 

हैरानी की बात है लिखा था, ERROR! WHY DONT U UNDERSTAND?मुद्रण दो बार हालांकि यह ज्यादा दिखाई देता है fork() कहा जाता है और ऐसा करना चाहिए पहले की जाती है केवल माता-पिता द्वारा मुद्रित किया जाना चाहिए।

क्या कोई इस पर कुछ प्रकाश डाल सकता है?

+0

मैं इस एक के बारे में यकीन नहीं है, लेकिन यकीन है कि आप कब-बफ़र्स फ्लश, कांटा से पहले बनाते हैं। शायद बफर बच्चे को कॉपी हो जाते हैं। – lupz

+2

यह एक उत्कृष्ट साक्षात्कार प्रश्न के लिए तैयार होगा! – dasblinkenlight

उत्तर

10

reopen के बाद से स्ट्रीम गैर-इंटरैक्टिव है, यह पूरी तरह से buffered है और '\n' पर फ्लश नहीं करता है। fork से पहले कहा जाता है बफर अभी भी संदेश है, और fork के बाद इस बफ़र संदेश दोहराया गया (क्योंकि दोनों प्रक्रियाओं stdout का अपना प्रतियां मिल गया) और फिर दोनों माता पिता और बच्चे द्वारा प्लावित। सी मानक के भाग 7.19.3 देखें।

आप fflush बुला सिर्फ fork से पहले से इस तरह के व्यवहार से बच सकते हैं।

+0

मुझे पता है कि \ n' पुनर्निर्देशन के बाद स्वचालित फ्लशर के रूप में काम नहीं करता है। धन्यवाद और +1 –

+0

आप 'stdout' को पुन: कॉन्फ़िगर करने के लिए 'setvbuf' का भी उपयोग कर सकते हैं। –

3

यह बफरिंग के कारण है। printf के ठीक बाद fflush करें।

दोनों प्रक्रियाएं stdio की आंतरिक सामग्री की एक ही प्रति के साथ समाप्त होती हैं और दोनों इसे exit पर फ़्लश करने के लिए आगे बढ़ती हैं। यदि आप बच्चे में _exit पर कॉल करते हैं तो आप इसे रोकने से भी रोक सकते हैं।

+0

यदि मैं 'exit()' '_exit()' में बदलता हूं, तो बच्चा कुछ भी प्रिंट नहीं कर रहा है। यानी 'मैं हूँ बच्चे' आउटपुट से गायब है। 'निकास()' और '_exit()' के बीच क्या अंतर है? –

+1

@Stacker '_exit' stdio buffers को फ्लश नहीं करता है। – cnicutar

1

बफर निस्तब्धता समस्या का समाधान होगा। प्रिंट स्टेटमेंट के ठीक बाद fflush का उपयोग करें।

0

ऐसा लगता है कि अभी भी ERROR! WHY DONT U UNDERSTAND forking के बाद बफ़र है और दोनों प्रक्रियाओं द्वारा लिखित हो जाता है।

सही होने के बाद अपने पहले printf() आंतरिक बफर प्लावित है और यह केवल आपकी फ़ाइल में एक बार लगता है कि आप

fflush(stdout); 

जोड़ें।

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