यहां महत्वपूर्ण पृष्ठभूमि यह है कि डिफ़ॉल्ट सेटअप के रूप में मानक द्वारा लाइन बफ़र किया stdout
जाना आवश्यक है ।
यह \n
आउटपुट को फ्लश करने का कारण बनता है ।
चूंकि दूसरे उदाहरण में न्यूलाइन नहीं है, इसलिए आउटपुट को फ्लश नहीं किया जाता है और जैसा fork()
कि पूरी प्रक्रिया को कॉपी करता है, यह stdout
बफर की स्थिति को भी कॉपी करता है ।
अब, fork()
आपके उदाहरण में ये कॉल कुल मिलाकर 8 प्रक्रियाएँ बनाते हैं - ये सभी stdout
बफर की स्थिति की एक प्रति है ।
परिभाषा के अनुसार, ये सभी प्रक्रियाएं कॉल exit()
करते समय से लौटती हैं main()
और exit()
कॉल के fflush()
बाद fclose()
सभी सक्रिय stdio धाराओं पर। इसमें शामिल है stdout
और परिणामस्वरूप, आप एक ही सामग्री को आठ बार देखते हैं।
कॉल करने fflush()
से पहले लंबित आउटपुट के साथ सभी धाराओं को कॉल करना fork()
या कांटेक्टेड बच्चे को स्पष्ट रूप से कॉल करने देना अच्छा है _exit()
जो केवल प्रक्रिया को स्टीडियो धाराओं को प्रवाहित किए बिना बाहर निकालता है।
ध्यान दें कि कॉलिंग exec()
stdio बफ़र्स को फ्लश नहीं करता है, इसलिए यदि आप ( fork()
कॉल करने के बाद ) exec()
और (यदि वह विफल रहता है) कॉल तो stdio बफ़र्स की परवाह नहीं करना ठीक है _exit()
।
BTW: यह समझने के लिए कि गलत बफ़रिंग का कारण हो सकता है, यहाँ लिनक्स में एक पूर्व बग है जिसे हाल ही में ठीक किया गया है:
मानक को stderr
डिफ़ॉल्ट रूप stderr
से अप्रभावित रहने की आवश्यकता होती है, लेकिन लिनक्स ने इस पर ध्यान नहीं दिया और लाइन को बफ़र कर दिया और (इससे भी बदतर) पूरी तरह से बफ़र कर दिया कि स्टडर को एक पाइप के माध्यम से रीडायरेक्ट किया गया था। इसलिए UNIX के लिए लिखे गए प्रोग्रामों ने लिनक्स पर बहुत देर से नई लाइन के बिना आउटपुट सामान किया।
नीचे टिप्पणी देखें, यह अब तय हो गया है।
इस लिनक्स समस्या के आसपास काम करने के लिए मैं यही करता हूं:
/*
* Linux comes with a broken libc that makes "stderr" buffered even
* though POSIX requires "stderr" to be never "fully buffered".
* As a result, we would get garbled output once our fork()d child
* calls exit(). We work around the Linux bug by calling fflush()
* before fork()ing.
*/
fflush(stderr);
यह कोड अन्य प्लेटफार्मों पर नुकसान नहीं पहुंचाता है क्योंकि fflush()
एक धारा पर कॉल करने से जो सिर्फ फ्लश किया गया था वह एक नॉओप है।
./prog1 > prog1.out
) या एक पाइप (./prog1 | cat
) के आउटपुट के साथ प्रोग्राम 1 चलाने का प्रयास करें । अपने दिमाग को उड़ाने के लिए तैयार रहें। :