2012-04-25 11 views
8

के बफरिंग व्यवहार को समझना मैं लिनक्स पर एक पाइप पर डेटा लिखने के लिए फ़ंक्शन कॉल fwrite() का उपयोग कर रहा हूं।fwrite()

इससे पहले, fwrite() डेटा के छोटे-छोटे टुकड़ों (औसत 20 बाइट्स) बार-बार और बफरिंग fwrite() को छोड़ दिया गया था के लिए बुलाया जा रहा है। प्रक्रिया पर स्ट्रेस ने दिखाया कि एक समय में 4096 बाइट डेटा लिखा जा रहा था।

यह पता चला कि यह लेखन प्रक्रिया मेरे कार्यक्रम में बाधा थी। तो मैंने 64 केबी के ब्लॉक में अपने कोड में डेटा बफर करने का निर्णय लिया और फिर fwrite() का उपयोग करके एक ही समय में संपूर्ण ब्लॉक लिखें। मैंने FILE * सूचक को 'नो बफरिंग' पर सेट करने के लिए setvbuf() का उपयोग किया।

प्रदर्शन सुधार उतना महत्वपूर्ण नहीं था जितना कि मुझे उम्मीद थी।

अधिक महत्वपूर्ण बात यह है कि strace आउटपुट से पता चला कि डेटा एक समय में 4096 बाइट्स लिखा जा रहा था। क्या कोई इस व्यवहार को मेरी व्याख्या कर सकता है? यदि मैं 6412 बी डेटा के साथ fwrite() पर कॉल कर रहा हूं, तो यह एक समय में केवल 4096 बाइट क्यों लिख रहा है?

क्या FILE * सूचक का उपयोग कर पाइप में डेटा लिखने के लिए fwrite() का कोई विकल्प है?

+0

क्या आप हमें कोड दिखा सकते हैं? – tuxuday

+1

@Shailesh_Tainwala: आप सी ++ में अपना कोड लिख रहे हैं, लेकिन यह सी ++ की बजाय एक सी प्रश्न है। 'fwrite()' एक सी फ़ंक्शन है, सी ++ फ़ंक्शन नहीं। मैंने आपके प्रश्न में एक सी टैग जोड़ा ताकि आप व्यापक दर्शक प्राप्त कर सकें। –

उत्तर

8

4096 लिनक्स मशीनरी से आता है जो पाइपलाइनों को कम करता है। ऐसा होता है कि दो जगहें होती हैं। एक पाइपलाइन की क्षमता है। क्षमता लिनक्स के पुराने संस्करणों पर एक सिस्टम पेज है, जो 32 बिट i386 मशीन पर 4096 बाइट्स है। (लिनक्स के अधिक आधुनिक संस्करणों पर क्षमता 64K है।)

दूसरी जगह जो आप उस 40 9 6 बाइट्स समस्या में भाग लेंगे, परिभाषित निरंतर PIPE_BUF, बाइट्स की संख्या परमाणु रूप से इलाज की गारंटी है। लिनक्स पर यह 40 9 6 बाइट है। इस सीमा का अर्थ इस बात पर निर्भर करता है कि आपने पाइपलाइन को अवरुद्ध करने या गैर-अवरुद्ध करने के लिए सेट किया है या नहीं। सभी गोरी विवरणों के लिए man -S7 pipe करें।

यदि आप उच्च दर पर डेटा की विशाल मात्रा का आदान-प्रदान करने की कोशिश कर रहे हैं तो आप पाइप के उपयोग पर पुनर्विचार करना चाहेंगे। आप एक लिनक्स बॉक्स पर हैं, इसलिए साझा स्मृति एक विकल्प है। आप सिग्नलिंग तंत्र के रूप में अपेक्षाकृत कम मात्रा में डेटा भेजने के लिए पाइप का उपयोग कर सकते हैं।

+0

एक और संभावित लिनक्स केवल विकल्प fwrite() के बजाय खुले() और splice() का उपयोग करना होगा। –

4

आप बफरिंग व्यवहार को बदलना चाहते हैं, तो आप ऐसा तुरंत करना चाहिए के बाद fopen (या किसी भी मैंने पहले/हे, मानक filehandles stdin, stdout, stderr के लिए)। आप बफरिंग को अक्षम नहीं करना चाहते हैं और बफर को स्वयं प्रबंधित करने का प्रयास करें; बल्कि, अपने 64 के बफर को setvbuf पर निर्दिष्ट करें ताकि इसका उपयोग ठीक से किया जा सके।

यदि आप वास्तव में बफरिंग मैन्युअल रूप से प्रबंधित करना चाहते हैं, तो stdio का उपयोग न करें; निम्न स्तर open, write, और close कॉल का उपयोग करें।

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