2010-04-26 20 views
14

और क्या इसमें कोई ऊपरी सीमा है कि इसमें कितना डेटा हो सकता है?क्या लिनक्स में एक पाइप डेटा खो सकता है?

+7

इसकी कमी नहीं हुई है। ढीला एक ढीला दांत –

+3

@intuited: खराब डिलीमीटर ")" (खुले दिशानिर्देश गायब हैं) – sleblanc

+0

मेरा दिन बना दिया, 4 और वर्ण जाओ :) – Aftnix

उत्तर

20

एक मशीन दुर्घटना वर्जित है, कोई यह डेटा खो नहीं कर सकते। इसका दुरुपयोग करना आसान है और लगता है कि आप डेटा खो रहे हैं, या तो क्योंकि लेखन आपके द्वारा अनुरोधित सभी डेटा लिखने में विफल रहा है और आपने वापसी मूल्य की जांच नहीं की है या आपने पढ़ने के साथ कुछ गलत किया है।

डेटा इसे पकड़ कर सकते हैं की अधिकतम राशि प्रणाली निर्भर है - अगर आप की तुलना में अधिक लिखने की कोशिश, तो आप या तो एक छोटी लिखने मिल जाएगा या जब तक स्थान उपलब्ध है लेखक रोकेंगे। pipe(7) मैन पेज में पाइप के बारे में बहुत सारी उपयोगी जानकारी है, जिसमें (कम से कम लिनक्स पर) बफर कितना बड़ा है। संस्करण के आधार पर लिनक्स में 4K या 64K के बफर हैं।

संपादित

टिम उल्लेख SIGPIPE है, जो भी एक संभावित मुद्दा यह है कि डेटा खोने के लिए लग सकता है है। यदि पाठक इसमें सबकुछ पढ़ने से पहले पाइप को बंद कर देता है, तो अपठित डेटा फेंक दिया जाएगा और लेखक को एक सिगिप सिग्नल मिलेगा जब वे अधिक लिखते हैं या पाइप बंद करते हैं, यह दर्शाता है कि यह हुआ है। अगर वे सिगिपिप को अवरुद्ध या अनदेखा करते हैं, तो उन्हें एक ईपीआईपीई त्रुटि मिल जाएगी। इसमें पॉल की स्थिति शामिल है।

PIPE_BUF एक स्थिर है जो आपको परमाणु बफर को लिखता है। कोई भी इस आकार या छोटे को लिखता है या तो पूरी तरह से सफल हो जाएगा या जब तक यह पूरी तरह सफल नहीं हो जाता है (या पाइप गैर-अवरुद्ध मोड में है तो EWOULDBLOCK/EAGAIN दें)। इसका कर्नेल के पाइप बफर के वास्तविक आकार से कोई संबंध नहीं है, हालांकि स्पष्ट रूप से बफर को कम से कम PIPE_BUF आकार में परमाणुता गारेने को पूरा करने के लिए होना चाहिए।

+0

मैंने वास्तव में इसे लोड करने के बाद अपना जवाब छोड़ दिया। आप SIGPIPE का उल्लेख करना चाहेंगे, http://en.wikipedia.org/wiki/SIGPIPE –

+0

एक ऐसा परिदृश्य हो सकता है जहां आप लेखक या पाठक को मार दें ताकि लेखक सोचता है कि पाठक ने कुछ नहीं लिखा है? सीमाओं में –

+0

PIPE_BUF आपको बताएगा कि सीमा कितनी बड़ी है। _PC_PIPE_BUF के साथ sysconf() आपको रनटाइम पर बता सकता है (वैसे भी लिनक्स पर) – frankc

2

आप खोल में | ऑपरेटर का उपयोग तो नहीं, यह डेटा नहीं खोएंगे की बात कर रहे हैं। यह केवल दाईं तरफ के मानक इनपुट स्ट्रीम पर ऐप को बाईं ओर की मानक आउटपुट स्ट्रीम पर ऐप से जोड़ता है। यदि आप ऐप्स के बीच डेटा पाइप कर रहे हैं और आपको अपेक्षित नतीजे नहीं मिल रहे हैं, तो पहले ऐप से मानक आउटपुट को फ़ाइल में रीडायरेक्ट करने के लिए > का उपयोग करने का प्रयास करें और फिर उस फ़ाइल का उपयोग दूसरे ऐप के लिए मानक इनपुट के रूप में करने के लिए < का उपयोग करें। इस तरह, आप फ़ाइल एएमडी का निरीक्षण कर सकते हैं यह सुनिश्चित कर लें कि आपके द्वारा अपेक्षित प्रारूप में डेटा भेजा जा रहा है।

तो तुम्हारा मतलब एक पाइप pipe समारोह के द्वारा बनाई गई तो जवाब अभी भी नहीं है। this man page के मुताबिक, एक पूर्ण पाइप को लिखना तब तक अवरुद्ध होगा जब तक कि डेटा लिखने के लिए पर्याप्त डेटा पढ़ा न जाए। यह भी बताता है कि एक पाइप का आकार लिनक्स प्री-2.6.11 में 4 केबी है, और यह 2.6.11 और बाद में 64 केबी है।

1

कारण आप डेटा खोने का कारण यह नहीं है कि जब पाइप से जुड़ा बफर write पर कॉल करता है तब तक अवरुद्ध हो जाएगा जब तक पाठक ने ऑपरेशन के लिए पर्याप्त बफर खाली नहीं किया हो। (आप गैर-अवरुद्ध लेखन भी कर सकते हैं, लेकिन फिर आप यह सुनिश्चित करने के लिए ज़िम्मेदार हैं कि आप किसी भी लिखने को अवरुद्ध कर दें।)

2

आपकी पाइप डेटा खो नहीं रही है। यदि आप अपने आवेदन में डेटा खो रहे हैं, तो इसे जीडीबी के साथ डीबग करने का प्रयास करें। योग्य कुछ बातें देखने के लिए:
1) अपने बफर इतना बड़ा कि सभी डेटा आप पढ़ रहे हैं पकड़ करने के लिए है?
2) त्रुटियों के लिए पाइप पर अपने पढ़ने() से रिटर्न कोड देखें।
3) क्या आप वाकई पाइप में सभी डेटा लिख ​​रहे हैं?
4) क्या आपका लेखन/पढ़ना ऑपरेशन सिग्नल द्वारा बाधित हो रहा है? यानी: सिगिप?

3

डाटा एक पाइप में खो जा सकता है जब निम्न होता है:

  1. एक प्रक्रिया (लेखक) पाइप, जहां n≤ PIPE_BUF के लिए डेटा के एन बाइट्स लिखता है। यह लेखन परमाणु होने की गारंटी है और कभी भी अवरुद्ध नहीं होगा।
  2. एक प्रक्रिया (पाठक) केवल एम < एन बाइट डेटा और बाहर निकलता है।
  3. लेखक फिर से पाइप को लिखने का प्रयास नहीं करता है।

नतीजतन, कर्नेल पाइप बफर में एन-एम बाइट्स होंगे जो पाइप पर सभी हैंडल बंद होने पर खो जाएंगे। लेखक SIGPIPE या EPIPE नहीं देख पाएंगे क्योंकि यह कभी भी पाइप को फिर से लिखने का प्रयास नहीं करता है। चूंकि लेखक कभी नहीं सीखेंगे कि पाइप में बचे हुए डेटा हैं जो आसानी से गायब हो जाएंगे, कोई भी इस डेटा को खोने पर विचार कर सकता है।

यह पता लगाने का एक गैर-मानक तरीका लेखक के लिए टाइमआउट को परिभाषित करने और पाइप बफर में छोड़े गए बाइट्स की संख्या निर्धारित करने के लिए FIONREAD ioctl पर कॉल करना होगा।

+0

क्या वह FIONREAD नहीं होना चाहिए? कम से कम FIONREAD लिनक्स पर नोट इंगित करता है कि लेखन वर्णनकर्ता (उदाहरण के लिए stdout) पर कितना डेटा अपठित है, लेकिन ऐसा लगता है कि पाठक दूर नहीं गया है। यह मेरे लिए उपयोगी लगता है अगर कर्नेल को लेखक को सिगिप भेजने का कोई तरीका था, तो पाठक सभी डेटा पढ़ने के बिना चला गया – pixelbeat

+0

धन्यवाद, टाइपो को ठीक किया गया। दरअसल, 'FIONREAD' यह इंगित नहीं करता है कि पाठक चले गए हैं, इसलिए समय-समय को परिभाषित करने की आवश्यकता है। हाँ, अगर मैं 'सिगिपी' भेजा गया तो मुझे यह भी उपयोगी लगेगा। – eigengrau82

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