实用程序来缓冲管道中无限数量的数据吗?


13

有没有可以贴在管道中的实用程序来降低读写速度?

$ producer | buf | consumer

基本上,我希望有一个实用程序buf能够尽可能快地读取其输入,并将其存储在内存中,以便在尽可能快地运行consumer时花费它的美好时光producer


我希望看到这样太
安蒂·哈帕拉

stdbuf工具似乎是一个size参数。我不确定是否可以。
CMCDragonkai '18年

Answers:


13

pv(管浏览器)实用程序可以做到这一点(有-B选项)和更多的事情,包括让你的进度报告。


有没有办法用无限量的数据来做到这一点?尽我所能告诉我,我需要提供一个带有-B的数字,如果生产者领先于消费者,生产者将再次放慢速度。如果您有多个使用者(producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2),可能会再次导致速度降低。
Daniel H

我已经使用了pv数百次,却从未听说过。非常棒,谢谢!
2014年

pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null-我希望两个pvs两端都很平滑(尽管一个s提前1GB)。与mbuffer
Vi

9

您可以使用dd

producer | dd obs=64K | consumer

每个Unix上都可用。


+1用于使用标准实用程序,尽管pv使用起来可能更好(显示进度)。
Totor

2
这实际上会影响读写速度吗?似乎一次dd只能存储一个块,因此,这只会延迟所有时间,产生块大小所花费的时间也是如此。如果我错了,请纠正我。另外,是否可以将此缓冲扩展到无限大小,或者仅扩展为块大小输入的内容?
Daniel H

@DanielH-现在开始。
mikeserv

7

看一下mbuffer。它可以缓冲到内存或内存映射文件(-t/ -T)。


正如我要求的其他方法一样,是否有一种方法可以告诉它尽可能多地缓冲,或者它具有最大大小?为什么有这些程序中的大多数程序确实具有最大大小,而不使用例如较小缓冲区的链表(或任何其他任意大小的队列实现)的概念原因?
Daniel H

可能是为了防止内存不足错误。如果需要,您可以使用一个选项来设置一个很大的缓冲区(大约4GB)(尝试一下)。
DavidBalažic'16

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尽管32MB缓冲区足够大,但是将大小增加到例如32M不会改变行为。我怀疑这是因为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_pipelinemapopentounixsocket

$ ./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] [         <=>      ]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.