psutil.Popen完成之后但终止之前,如何获取cpu_times的进程运行

时间:2019-03-21 23:03:23

标签: python subprocess psutil

我想使用cpu_times()对象的psutil.Popen方法来找到完成后的累积值。我首先尝试了以下方法:

p = psutil.Popen("stress --cpu 3 -v -t 15", shell=True)
p.wait()
cpuTimes = p.cpu_times()

但是,这会导致NoSuchProcess异常,因为wait()在进程终止之前不会返回。接下来,我尝试将呼叫移至cpu_times()之前之前:

wait()

但是,这会产生全零的响应。我认为这是因为在过程开始后立即调用了它。因此,我添加了一个对p = psutil.Popen("stress --cpu 3 -v -t 15", shell=True) cpuTimes = p.cpu_times() p.wait() 的调用,该调用将使该过程耗时更长:

time.sleep()

这实际上产生了45秒的期望值(3个CPU,利用率为100%,持续15秒)。

但是,对于一般过程,我将不知道需要多长时间才能完成。我想避免添加任意大的睡眠时间,只是为了确保在查询之前完成该过程。

是否有一种方法可以知道在不返回p = psutil.Popen("stress --cpu 3 -v -t 15", shell=True) time.sleep(15.) # b/c -t 15 in subprocess means it will take 15 seconds cpuTimes = p.cpu_times() p.wait() 或其他此类方法的情况下该过程已完成?

1 个答案:

答案 0 :(得分:1)

好的,我找到了解决方案。它实际上非常简单,因此我可能在发布问题之前就应该考虑过这一点,但是我想这有时就是这样。

p = psutil.Popen("stress --cpu 3 -v -t 15", shell=True)
cpuTimes = p.cpu_times()
while True:
    time.sleep(1e-4)
    cpuTimes = p.cpu_times()  # Make sure to do this before the call to poll()
    retCode = p.poll()
    if retCode is not None:
        break

在这里,我在启动包含对的调用的子流程之后添加了一个循环 该过程的cpu_times()poll()方法。

poll()方法是检查子进程是否已完成的一种非阻塞方式。通过在调用cpu_times()之前立即调用poll(),将花费很少的时间,因此,出于所有意图和目的,我们可以考虑最后一次调用cpu_times()以产生一个准确的结果。

请注意,如果过程已完成,则在cpu_times()之后调用poll()时会出现异常。这是将呼叫cpu_times()放在poll()之前的另一个原因。

sleep()方法的参数不是很重要,但是会影响子过程完成之后和循环终止之前将花费多少时间。如果子进程从未完成,您可能还可以添加某种慷慨的超时来防止无限循环。