2 पॉइंट द्वारा GN⁺ 2024-11-30 | 1 टिप्पणियां | WhatsApp पर शेयर करें

पाइप "रुक" क्यों जाता है: buffering

  • समस्या का विवरण: जब लॉग फ़ाइल में किसी खास आउटपुट को खोजने के लिए tail -f /some/log/file | grep thing1 | grep thing2 कमांड चलाया जाता है, तो अगर लॉग लाइनें धीरे-धीरे जुड़ रही हों तो आउटपुट दिखाई नहीं देता। इससे लगता है कि पाइप रुक गया है, लेकिन असल में प्रोग्राम पाइप में डेटा लिख ही नहीं रहा होता।

buffering का कारण

  • buffering क्यों होती है: आम तौर पर प्रोग्राम डेटा को पाइप या फ़ाइल में लिखने से पहले buffer करते हैं। ऐसा performance बेहतर करने के लिए किया जाता है, ताकि हर आउटपुट तुरंत लिखने के बजाय कुछ मात्रा में डेटा इकट्ठा करके एक साथ लिखा जाए।
  • उदाहरण: grep thing1 8KB डेटा इकट्ठा होने तक matched डेटा को रोककर रख सकता है, और इसी वजह से आउटपुट दिखाई नहीं दे सकता।

टर्मिनल पर लिखते समय buffering नहीं होती

  • टर्मिनल और पाइप का अंतर: grep जब आउटपुट टर्मिनल पर भेजता है तो line buffering का उपयोग करता है, लेकिन पाइप पर भेजते समय block buffering का उपयोग करता है। इसका फ़ैसला isatty फ़ंक्शन के ज़रिए होता है।

कौन-सी कमांड buffer करती हैं और कौन-सी नहीं

  • buffer न करने वाली कमांड: tail, cat, tee आदि buffer नहीं करतीं।
  • buffer करने वाली कमांड: grep, sed, awk, tcpdump, jq, tr, cut आदि buffer करती हैं, और इनमें से कुछ में खास flags के ज़रिए buffering बंद की जा सकती है।

प्रोग्रामिंग भाषाओं में डिफ़ॉल्ट आउटपुट buffering

  • buffer करने वाली भाषाएँ: C, Python, Ruby, Perl आदि डिफ़ॉल्ट रूप से output buffering करती हैं, और कुछ तरीकों से इसे बंद किया जा सकता है।

Ctrl-C दबाने पर buffer की सामग्री खो जाना

  • समस्या का विवरण: Ctrl-C दबाने पर buffer में मौजूद सामग्री खो जाती है। ऐसा इसलिए होता है क्योंकि SIGINT signal पहले पहुँचता है।
  • समाधान: tcpdump का PID ढूँढकर kill -TERM $PID चलाने पर buffer flush कराया जा सकता है।

फ़ाइल में redirect करने पर भी buffering होती है

  • फ़ाइल redirection: फ़ाइल में redirect करते समय भी buffering होती है, लेकिन Ctrl-C की वजह से buffer खोने वाली समस्या नहीं होती।

buffering से बचने के कई तरीके

  • समाधान 1: ऐसा प्रोग्राम चलाएँ जो जल्दी समाप्त हो जाए।
  • समाधान 2: grep का --line-buffered flag इस्तेमाल करें।
  • समाधान 3: awk का उपयोग करें।
  • समाधान 4: stdbuf का उपयोग करें।
  • समाधान 5: unbuffer का उपयोग करें।

buffering बंद करने के लिए environment variable

  • विचार: यह राय दी गई है कि PYTHON_UNBUFFERED जैसे standard environment variable होना अच्छा रहेगा। NO_BUFFER जैसे variable का सुझाव दिया गया है।

छोड़ी गई सामग्री

  • छोड़े गए विषय: line buffering और पूरी तरह unbuffered mode का अंतर, stderr और stdout की buffering का अंतर, operating system के TTY driver की buffering आदि।

1 टिप्पणियां

 
GN⁺ 2024-11-30
Hacker News टिप्पणियाँ
  • buffered access में तय byte count या समय बीतने पर flush होना चाहिए। hardware interfaces में इसी तरह की समस्या हल करने का यह एक सामान्य तरीका है

    • user space में buffering करने वाली library को data पहली बार buffer करते समय उपयुक्त timer सेट करना चाहिए
    • timeout parameter को argument के रूप में देना, या उसे मानव समय-पैमाने से थोड़ा कम रखना, या bandwidth/threshold के अनुपात में रखना, या flushing overhead के अनुपात में रखना बेहतर है
    • यह write और read दोनों पर लागू होता है, और data channel के अनुसार अलग हो सकता है
  • जब पूरे system का CPU idle हो जाए, तब सभी buffers को flush करना अच्छा होगा

    • buffering आम तौर पर CPU बचाने की तकनीक है
    • CPU idle होने पर सभी processes को "buffers flush करो" का signal भेजना चाहिए
  • 20 साल से ज़्यादा समय से NIX systems के साथ काम किया है, लेकिन buffering problems को हर बार भूल जाता हूँ

  • 35 साल से ज़्यादा समय से Unix इस्तेमाल किया है, लेकिन buffering कैसे काम करती है, यह पूरी तरह कभी नहीं समझ पाया। यह explanation उपयोगी लगी

  • लोग "unbuffered" और "line buffered" को गड़बड़ा रहे हैं

    • unbuffered mode performance को गिरा सकता है, और अगर कई sources एक ही pipe में लिख रहे हों तो गलत output बना सकता है
    • line buffering terminal का default है, और pipe के लिए उपयुक्त है
  • buffers इसलिए मौजूद हैं क्योंकि buffer में लिखना, स्क्रीन पर output print करने की तुलना में, अपेक्षाकृत बहुत धीमा होता है

    • UART के साथ काम करते समय यह अक्सर आने वाली समस्या है, और इसके कई solutions हैं
    • special characters का उपयोग, length-based approach, time-based approach जैसे कई तरीके हैं
  • Ctrl-C दबाने पर buffer की सामग्री खो सकती है

    • मेरा मानना था कि ज़्यादातर programs SIGINT पर buffer flush करेंगे
  • Unix में buffering issues का सामना किया है, और सभी 'awk' implementations एक जैसा व्यवहार नहीं करते

  • ऐसा लग रहा है कि जमे हुए pipe वाले मज़ाक को मैं समझ नहीं पाया