【问题标题】:python popen stdout freezingpython popen标准输出冻结
【发布时间】:2017-03-29 15:16:05
【问题描述】:

我已经阅读了许多涉及实时标准输出打印的问题,包括来自J.F. Sebastian's Python 3 solution 的答案 读取标准输出。

但是,虽然他的解决方案适用于这种情况:

with Popen(['ping'] + ['169.254.79.191'] + ['-c'] + ['5'], stdout=PIPE, bufsize=1, universal_newlines=True) as p:
    for line in p.stdout:
        print(line, end='')

对于我实际想要使用的应用程序,它无法正常工作:

with Popen(['iperf3', '-c', '169.254.79.191', 'b', '100000000', '-p', '5202', 't', '5', '-R', '-V', '-u'], stdout=PIPE, bufsize=1, universal_newlines=True) as p:
     for line in p.stdout:
         print(line, end='')

对于 ping 场景,每一行都像我手动运行一样打印。使用 iperf,它会在两行输出后停止,并在应用程序完成时刷新所有内容。 如果我在脚本中一个接一个地执行它们,我会得到这个输出:

pi@raspberrypi2:~/project $ python3.4 stdout_RT_test.py
PING 169.254.79.191 (169.254.79.191) 56(84) bytes of data.
64 bytes from 169.254.79.191: icmp_seq=1 ttl=64 time=0.854 ms
64 bytes from 169.254.79.191: icmp_seq=2 ttl=64 time=0.867 ms
64 bytes from 169.254.79.191: icmp_seq=3 ttl=64 time=0.877 ms
64 bytes from 169.254.79.191: icmp_seq=4 ttl=64 time=0.842 ms
64 bytes from 169.254.79.191: icmp_seq=5 ttl=64 time=0.834 ms

--- 169.254.79.191 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3998ms
rtt min/avg/max/mdev = 0.834/0.854/0.877/0.040 ms
iperf 3.0.7
Linux raspberrypi2 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux

在 IPERF 完成后显示此行之后的所有内容

Time: Wed, 29 Mar 2017 14:46:48 GMT
Connecting to host 169.254.79.191, port 5202
Reverse mode, remote host 169.254.79.191 is sending
      Cookie: raspberrypi2.1490798808.947399.0490a
[  4] local 169.254.181.167 port 41415 connected to 169.254.79.191 port 5202
Starting Test: protocol: UDP, 1 streams, 8192 byte blocks, omitting 0 seconds, 10 second test
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-1.00   sec   136 KBytes  1.11 Mbits/sec  1.907 ms  0/17 (0%)
[  4]   1.00-2.00   sec   128 KBytes  1.05 Mbits/sec  0.966 ms  0/16 (0%)
[  4]   2.00-3.00   sec   128 KBytes  1.05 Mbits/sec  0.634 ms  0/16 (0%)
[  4]   3.00-4.00   sec   128 KBytes  1.05 Mbits/sec  0.522 ms  0/16 (0%)
[  4]   4.00-5.00   sec   128 KBytes  1.05 Mbits/sec  0.466 ms  0/16 (0%)
[  4]   5.00-6.00   sec   128 KBytes  1.05 Mbits/sec  0.456 ms  0/16 (0%)
[  4]   6.00-7.00   sec   128 KBytes  1.05 Mbits/sec  0.452 ms  0/16 (0%)
[  4]   7.00-8.00   sec   128 KBytes  1.05 Mbits/sec  0.447 ms  0/16 (0%)
[  4]   8.00-9.00   sec   128 KBytes  1.05 Mbits/sec  0.451 ms  0/16 (0%)
[  4]   9.00-10.00  sec   128 KBytes  1.05 Mbits/sec  0.460 ms  0/16 (0%)
- - - - - - - - - - - - - - - - - - - - - - - - -
Test Complete. Summary Results:
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec  1.26 MBytes  1.06 Mbits/sec  0.460 ms  0/161 (0%)
[  4] Sent 161 datagrams
CPU Utilization: local/receiver 0.5% (0.0%u/0.5%s), remote/sender 0.0% (0.0%u/0.0%s)

iperf Done.

从间隔列中可以看出,如果我手动运行相同的命令,每秒大约会打印一行。我是 python 新手,所以任何错误都是可能的。我尝试了其他几种缓存标准输出的方法,但它们也会像这样冻结输出。这可以以某种方式解决吗?

BR 安德烈亚斯

编辑:我认为问题是 iperf 没有刷新,但由于它显然每秒都在写一个新行,所以必须有一种方法在刷新之前捕获它。当运行更长的测试时,我注意到标准输出缓冲区最终会被最大化,并且会刷新许多行并继续直到它再次满。

【问题讨论】:

  • 你试过the .readline() approach吗?
  • @9000 这给出了完全相同的结果,前两行打印然后它停止并等待一切完成。 iperf 3.0.7第一行Linux raspbery...第二行
  • 您是否尝试将bufsize in Popen constructor 设置为0?
  • @9000 是的,我也试过了。不幸的是,同样的结果。

标签: python linux iperf


【解决方案1】:

尝试将--forceflush 命令行标志添加到 iperf3。这会导致 iperf3 在每行输出后刷新其输出。

【讨论】:

    【解决方案2】:

    您还可以使用以下方法更改缓冲区值:

    stdbuf -i0 -o0 -e0 iperf3 ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      相关资源
      最近更新 更多