改变速率限制的管道查看器问题

Mor*_*inz 3 linux pv

pv用于通过ssh.

我可以在 100M 以下更改“active pv”限制,没有任何问题。当我将活动pv进程设置为 100M 或 1G 或更高时,我无法再更改速率...

但!如果我将 1M 更改为 2M 的 5-10 次,2M 到 1Mpv有时可以设置为新速率。

我找不到任何解决问题的方法。任何的想法?

例子:

pv -R "15778"  -f -F "%p***%t***%e***%r***%b" -L 1M  
pv -R "15778"  -f -F "%p***%t***%e***%r***%b" -L 1G  
pv -R "15778"  -f -F "%p***%t***%e***%r***%b" -L 1M (not working anymore)  
Run Code Online (Sandbox Code Playgroud)

Ste*_*itt 5

这是由记入 in 引起的pv,这实际上意味着它的速率限制是读限制而不是写限制。查看源代码表明,速率限制是由“目标”驱动的,即要发送的剩余数量。如果速率限制打开,则每个速率限制评估周期一次,目标将根据速率限制增加我们应该发送的数量;无论实际写入多少,目标都会减少。这意味着如果您将速率限制设置为大于实际写入容量的值,则目标将继续上升;在达到pv其目标(包括根据新的速率限制允许写入的内容)之前,降低速率限制不会产生任何影响。

要查看此操作,请启动一个基本的pv

pv /dev/zero /dev/null
Run Code Online (Sandbox Code Playgroud)

然后控制:

pv -R 32605 -L 1M; sleep 10; pv -R 32605 -L 1G; sleep 1; pv -R 32605 -L 1M
Run Code Online (Sandbox Code Playgroud)

通过改变第二次睡眠的持续时间,您将看到目标计算的影响......

由于写入限制,这只会在您将速率限制设置为大于写入容量的值时导致问题。

更详细地说,以下是在能够传输 400M 的连接上,最初限制为 1M,然后限制为 1G 5 秒,然后回到 1M 的流量的计费方式:

Time    Rate     Target Sent    Remaining
1       1M       1M     1M      0
2       1G       1G     400M    600M
3       1G       1.6G   400M    1.2G
4       1G       2.2G   400M    1.8G
5       1G       2.8G   400M    2.4G
6       1G       3.4G   400M    3G
7       1M       3001M  400M    2601M
8       1M       2602M  400M    2202M
9       1M       2203M  400M    1803M
10      1M       1804M  400M    1404M
11      1M       1405M  400M    1005M
12      1M       1006M  400M    606M
13      1M       607M   400M    207M
14      1M       208M   208M    0
15      1M       1M     1M      0
Run Code Online (Sandbox Code Playgroud)

再次应用限速需要7s。使用高速率限制的时间越长,执行降低的速率限制所需的时间就越长......

对此的修复非常简单,如果您可以重新编译pv: in loop.c,将第 154 行更改为target =(from target +=),从而导致

                   || (cur_time.tv_sec == next_ratecheck.tv_sec
                       && cur_time.tv_usec >=
                       next_ratecheck.tv_usec)) {
                       target =
                           ((long double) (state->rate_limit)) /
                           (long double) (1000000 /
                                          RATE_GRANULARITY);
Run Code Online (Sandbox Code Playgroud)

一旦完成,就会立即降低速率限制(好吧,在一个速率限制周期内)。