在python子例程中使用“time”时访问stdout

2024-05-26 11:07:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在shell中使用time命令进行一些手动基准测试。我想通过编写一个python脚本来扩展我的基准测试,这个脚本既可以自动化测试,又可以让我访问时间数据,这样我就可以用我选择的格式(可能是csv)记录它。我看到了timeit模块,但它似乎更适合于对python代码进行基准测试,这里我尝试对命令行中运行的程序进行基准测试。你知道吗

这就是我一直在做的:

time program -aflag -anotherflag

我最初尝试在脚本中实现这一点,如下所示:

cmnd = ['time', 'program', 'aflag', 'anotherflag']
p = subprocess.Popen(cmnd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate
print out
print err

我可以很好地访问time的输出–这是传递给stderr的,但是我没有像stdout中预期的那样获得program的输出。如果我从cmnd中删除time,并将shell=False更改为True,那么我将在stdout中获得程序的输出—但显然不是time的输出,这就是重点。你知道吗

cmnd = ['program', 'aflag', 'anotherflag']
p = subprocess.Popen(cmnd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate
print out
print err

如果我用shell=Truetime添加回cmnd,我会得到时间的输出,但是program实际上没有运行。你知道吗

我怎样才能让这两个都工作?你知道吗


Tags: 脚本timestderrstdout基准shelloutprogram
1条回答
网友
1楼 · 发布于 2024-05-26 11:07:24

为什么不在^{}模块中使用Python内置的功能呢?你知道吗

import resource
import subprocess

cmd = ['program', 'aflag', 'anotherflag']
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
usage = resource.getrusage(resource.RUSAGE_CHILDREN)
print out
print err
print usage.ru_utime, usage.ru_stime, usage.ru_utime+usage.ru_stime

如果需要区分同时运行的不同子进程,getrusage显然是不够的。在这种情况下,您需要使用^{}或类似的方法来获取每个进程的资源使用情况。这使得Popen的使用更加复杂。对于这种情况,您可能想做的是对subprocess代码进行子类化或分叉(但如果您使用的是3.1或更早版本,请确保使用^{}backport以避免communicate中的错误,这样类实际上就有了要挂接的方法……),并将the ^{} method更改为使用wait4而不是waitpid,并将额外的结果存储在self.rusage所以你以后可以访问它。你知道吗

我想这样的办法行得通:

import subprocess32

class Popen(subprocess32.Popen):
    def _try_wait(self, wait_flags):
        """All callers to this function MUST hold self._waitpid_lock."""
        try:
            (pid, sts, rusage) = _eintr_retry_call(os.wait4, self.pid, wait_flags)
            if pid == self.pid:
                self.rusage = rusage
        except OSError as e:
            if e.errno != errno.ECHILD:
                raise
            pid = self.pid
            sts = 0
        return (pid, sts)

cmd = ['program', 'aflag', 'anotherflag']
p = Popen(cmd, shell=False, stdout=subprocess32.PIPE, stderr=subprocess32.PIPE)
out, err = p.communicate()
print out
print err
try:
    usage = p.rusage
except AttributeError:
    print 'Child died before we could wait on it, no way to get rusage'        
else:
    print usage.ru_utime, usage.ru_stime, usage.ru_utime+usage.ru_stime

相关问题 更多 >