एक पाइप लाइन में डेटा की एक अनबाउंड राशि बफर करने के लिए उपयोगिता?


14

क्या एक उपयोगिता है जिसे मैं पढ़ने और लिखने की गति को कम करने के लिए एक पाइपलाइन में छड़ी कर सकता हूं?

$ producer | buf | consumer

मूल रूप से, मैं एक उपयोगिता चाहता हूं bufजो इसके इनपुट को जितनी जल्दी हो सके पढ़ता है, इसे मेमोरी में संग्रहीत करता है ताकि जितना संभव हो उतना तेज़ चलने में consumerइसका मीठा समय लग producerसके।


मैं ऐसे भी देखना चाहता हूं
एंट्टी हवाला

stdbufउपकरण एक प्रतीत होता है sizeपैरामीटर। मुझे यकीन नहीं है कि अगर यह काम करता है।
CMCDragonkai

जवाबों:


14

pv(पाइप दर्शक) उपयोगिता इस (के साथ कर सकते -Bआप प्रगति रिपोर्ट देने सहित, विकल्प) और एक बहुत अधिक।


क्या डेटा की अनबाउंड राशि के साथ ऐसा करने का कोई तरीका है? जितना अच्छा मैं बता सकता हूं, मुझे बी के साथ एक नंबर की आपूर्ति करने की आवश्यकता है और अगर निर्माता को उपभोक्ता से बहुत आगे मिलता है, तो निर्माता फिर से धीमा हो जाएगा। यदि आप ऐसी स्थिति में हैं जहां कई उपभोक्ता हैं ( producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2), तो यह फिर से मंदी का कारण बन सकता है।
डैनियल एच।

मैंने pvसैकड़ों बार उपयोग किया है और यह कभी नहीं जानता था। बहुत बढ़िया, धन्यवाद!
Rucent88

pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null- मुझे उम्मीद है कि दोनों pvछोरों को सुचारू किया जाएगा (हालांकि एक 1GB आगे है)। यह इस तरह से काम नहीं करता है, इसके विपरीतmbuffer
Vi।

9

आप उपयोग कर सकते हैं dd:

producer | dd obs=64K | consumer

यह हर यूनिक्स पर उपलब्ध है।


मानक उपयोगिता का उपयोग करने के लिए +1, हालांकि pvसंभवतः उपयोग करने के लिए अच्छा है (प्रगति दिखाता है)।
Totor

2
क्या यह वास्तव में पढ़ने और लिखने की गति को कम करता है? ऐसा लगता है कि ddएक समय में केवल एक ब्लॉक को स्टोर करता है, इसलिए ब्लॉक आकार का उत्पादन करने में जितना समय लगेगा, वह सब कुछ देरी से करेगा; कृपया मुझे सुधारें अगर मैं गलत हूं। इसके अलावा, क्या इस बफ़रिंग को असीमित आकार तक बढ़ाया जा सकता है, या केवल ब्लॉक आकार के लिए जो कुछ भी दर्ज किया गया है?
डैनियल एच।

@ डैनियल - यह अब करता है।
22

7

Mbuffer पर एक नज़र डालें । यह मेमोरी या मेमोरी मैप्ड फाइल ( -t/ -T) में बफर कर सकता है ।


जैसा कि मैंने दूसरों से पूछा, क्या यह बफर को यह बताने का एक तरीका है कि जितना आवश्यक है, या क्या इसका अधिकतम आकार है? क्या कोई वैचारिक कारण है कि इनमें से अधिकांश कार्यक्रमों में अधिकतम आकार होते हैं और उदाहरण के लिए, छोटे बफ़र्स (या किसी अन्य मनमाने आकार की कतार कार्यान्वयन) की लिंक की गई सूची का उपयोग नहीं करते हैं?
डैनियल एच

संभवतः आउट-ऑफ-मेमोरी त्रुटियों को रोकने के लिए। आप बहुत बड़े बफर (4GB या तो) सेट करने के लिए एक विकल्प का उपयोग कर सकते हैं यदि आप ऐसा चाहते हैं (इसे आज़माएं)।
डेविड बालैसिक

1

यह मूल रूप से एक नकारात्मक जवाब है। ऐसा प्रतीत होता है कि न तो dd, और न ही mbuffer, न ही pvकाम करता है सभी मामलों में विशेष रूप से है, निर्माता द्वारा उत्पन्न डेटा की दर एक बहुत अलग-अलग हो सकते हैं। मैं नीचे कुछ टेस्टकेस देता हूं। कमांड टाइप करने के बाद, लगभग 10 सेकंड तक प्रतीक्षा करें, फिर टाइप करें >(डेटा के अंत तक जाने के लिए, यानी इनपुट के अंत तक प्रतीक्षा करें)।

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | dd bs=64K | less

यहां, टाइप करने के बाद >, 5 सेकंड के लिए इंतजार करना पड़ता है, जिसका अर्थ है कि निर्माता (zsh स्क्रिप्ट) ने पहले ब्लॉक कर दिया है sleep 5bsआकार में वृद्धि करने के लिए उदाहरण के लिए 32M व्यवहार में बदलाव नहीं करता है, हालांकि 32 एमबी बफर काफी बड़ा है। मुझे संदेह है कि यह ddइनपुट के साथ जाने के बजाय आउटपुट पर ब्लॉक है। उपयोग करना oflag=nonblockएक समाधान नहीं है क्योंकि यह डेटा को डिस्क्राइब करता है।

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | mbuffer -q | less

इसके साथ mbuffer, समस्या यह है कि पहली पंक्ति (foo0) तुरंत दिखाई नहीं देती है। इनपुट पर लाइन-बफ़रिंग को सक्षम करने के लिए कोई विकल्प प्रतीत नहीं होता है।

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | pv -q -B 32m | less

के साथ pv, व्यवहार के समान है dd। इससे भी बदतर, मुझे संदेह है कि यह टर्मिनल के लिए गलत काम करता है क्योंकि कभी-कभी टर्मिनल से lessइनपुट प्राप्त नहीं किया जा सकता है; उदाहरण के लिए, कोई इसे छोड़ नहीं सकता है q


0

अमानक चाल: सॉकेट बफ़र्स का उपयोग करना।

उदाहरण:

# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
        i:  468MB 0:00:16 [ 129kB/s] [  <=>                        ]
        o: 1.56MB 0:00:16 [ 101kB/s] [       <=>                   ]

इसके लिए दो अतिरिक्त टूल लागू किए गए: बफ़र किए गए_पिपलीन और मैपोपेंटाउनिक्सोस्कैट

$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
        1: 13.4MB 0:00:40 [ 103kB/s] [         <=>      ]
        2: 3.91MB 0:00:40 [ 100kB/s] [         <=>      ]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.