ยูทิลิตี้เพื่อบัฟเฟอร์จำนวนข้อมูลที่ไม่ จำกัด ในไปป์ไลน์หรือไม่?


14

มียูทิลิตี้ที่ฉันสามารถติดในไปป์ไลน์เพื่อแยกความเร็วในการอ่านและเขียนได้หรือไม่?

$ producer | buf | consumer

โดยทั่วไปฉันต้องการยูทิลิตี้bufที่อ่านอินพุตเร็วที่สุดเท่าที่จะเป็นไปได้เก็บไว้ในหน่วยความจำเพื่อให้consumerสามารถใช้ช่วงเวลาที่หวานในขณะที่producerรันเร็วที่สุด


ฉันต้องการเห็นเช่นกัน
Antti Haapala

stdbufเครื่องมือที่ดูเหมือนจะเป็นsizeพารามิเตอร์ ฉันไม่แน่ใจว่าทำงานได้หรือไม่
CMCDragonkai

คำตอบ:


14

pv(ผู้ชมท่อ) ยูทิลิตี้สามารถทำเช่นนี้ (ที่มี-Bตัวเลือก) และอื่น ๆ อีกมากมายรวมทั้งให้คุณรายงานความคืบหน้า


มีวิธีการทำเช่นนี้กับข้อมูลจำนวนไม่ จำกัด ? อย่างดีที่สุดที่ฉันสามารถบอกได้ว่าฉันต้องจัดหาตัวเลขด้วย -B และหากผู้ผลิตได้รับมาก่อนผู้บริโภคผู้ผลิตจะช้าลงอีกครั้ง หากคุณอยู่ในสถานการณ์ที่มีผู้บริโภคหลายราย ( producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2) สิ่งนี้อาจทำให้การชะลอตัวอีกครั้ง
Daniel H

ฉันใช้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
ที่จริงแล้ว decouple ความเร็วในการอ่านและการเขียน? ดูเหมือนว่าddจะเก็บเพียงหนึ่งบล็อกในแต่ละครั้งดังนั้นมันจะล่าช้าทุกอย่างตามระยะเวลาที่ใช้ในการผลิตขนาดบล็อก โปรดแก้ไขฉันหากฉันผิด นอกจากนี้การบัฟเฟอร์นี้สามารถขยายเป็นขนาดไม่ จำกัด ได้หรือเฉพาะสิ่งที่ป้อนสำหรับขนาดบล็อกเท่านั้น
Daniel H

@DanielH - ทำได้แล้ว
mikeserv

7

ลองดูที่mbuffer มันสามารถบัฟเฟอร์หน่วยความจำหรือไฟล์ที่แมปหน่วยความจำ ( -t/ -T)


เมื่อฉันถามคนอื่น ๆ มีวิธีบอกให้บัฟเฟอร์มากเท่าที่จำเป็นหรือมีขนาดสูงสุดหรือไม่? มีเหตุผลทางความคิดหรือไม่ว่าทำไมโปรแกรมเหล่านี้ส่วนใหญ่มีขนาดสูงสุดและไม่ยกตัวอย่างเช่นใช้รายการที่เชื่อมโยงของบัฟเฟอร์เล็ก ๆ (หรือการนำคิวขนาดอื่นไปใช้)
Daniel H

อาจป้องกันข้อผิดพลาดออกจากหน่วยความจำ คุณอาจใช้ตัวเลือกในการตั้งค่าบัฟเฟอร์ที่มีขนาดใหญ่มาก (4GB หรือมากกว่านั้น) หากคุณต้องการ (ลอง)
David Balažic

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 5ได้บล็อกก่อน การเพิ่มbsขนาดเป็น 32M ไม่ได้เปลี่ยนพฤติกรรม แต่บัฟเฟอร์ 32MB นั้นใหญ่พอ ฉันสงสัยว่าเป็นเพราะ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และmapopentounixsocket

$ ./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] [         <=>      ]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.