如何使用Python从fio捕获非阻塞实时输出

时间:2016-01-29 23:59:06

标签: python subprocess

>>>x = subprocess.Popen(["fio", "--filename=/dev/sdd", "--name=job1", "--numjobs=2"], stdout=subprocess.PIPE)

但我需要实时捕捉fio progess。我虽然做了一个线程subprocess.stdout.readline,但它似乎没有更新性能数据:

>>> x = subprocess.Popen(["fio", "--filename=/dev/sdd", "--name=job1", "--numjobs=2"], stdout=subprocess.PIPE)

>>> x.stdout.readline()  
'job1: (g=0): rw=read, bs=4K-4K/4K-4K/4K-4K, ioengine=sync, iodepth=1\n'

>>> x.stdout.readline()  
'...\n'

>>> x.stdout.readline()  
'fio-2.2.11\n'

>>> x.stdout.readline()  
'Starting 2 processes\n'

>>> x.stdout.readline()  

它在此之后就会挂起。

fio的命令行执行如下:

[root@goblinbank tmp]# fio --filename=/dev/sdd --name=job1 --numjobs=2
job1: (g=0): rw=read, bs=4K-4K/4K-4K/4K-4K, ioengine=sync, iodepth=1
...
fio-2.2.11
Starting 2 processes
Jobs: 2 (f=2): [R(2)] [0.2% done] [246.3MB/0KB/0KB /s] [63.5K/0/0 iops] [eta 02h:26m:09s]

"工作后的文字:2(f = 2):[R(2)]"不断刷新新值。

2 个答案:

答案 0 :(得分:2)

这解决了问题:

<ion-view ng-controller="CatagoryItemsContoller">
    <div class="item item-input item-select item-margin">
        <div class="input-label">
            Pick
        </div>
        <select ng-model="selectedItem" ng-options="o as o for o in stringArr"></select>
    </div>
</ion-view>

注意fio中的x = subprocess.Popen(["fio", "--filename=/dev/sdd", "--name=job1", "--numjobs=2", "--eta=always"], stdout=subprocess.PIPE, universal_newlines=True) 标志和Popen中的--eta=always参数。

更多信息here

答案 1 :(得分:1)

然后,您可以使用fcntl将其设置为非阻塞IO,如果无法读取数据,则会引发异常。只需添加:

fcntl.fcntl(process.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
创建流程后

并验证是否有使用try / except IOError子句读取的内容,如下所示:

import fcntl
import os
import shlex
import subprocess
import time

cmd = 'fio --filename=/home/turicas/data/test.tmp --name=job1 --numjobs=2'
process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
fcntl.fcntl(process.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

data = None
while data != '':
    try:
        data = process.stdout.readline()
    except IOError:
        print 'no data. waiting...'
        time.sleep(0.1)  # wait stdout output to be available
    else:
        print 'data read:', data
print 'stdout closed'