当前位置: 首页 > 面试题库 >

带/ usr / bin / time的Python子进程:如何捕获时序信息,但忽略所有其他输出?

萧晓博
2023-03-14
问题内容

我试图以秒为单位来衡量通过子流程调用的可执行程序的执行时间。我不希望发出可执行文件(stderr或stdout)的输出。

我已经尝试了timeit和资源库,但是都没有准确地捕获进程的时间,似乎它只捕获了Python worker线程中的时间。

下面的这种尝试将丢失stderr重定向的时序信息b / c。但是,不带stderr重定向,将发出命令’f_cmd’stderr输出。

def doWithTiming(f_cmd):
    DEVNULL = open(os.devnull, 'w')
    return subprocess.check_output([ "/usr/bin/time", "--format=%e seconds"] + f_cmd.split(), stderr=DEVNULL)

如何忽略f_cmd的所有输出,但保留/ usr / bin / time的输出?


问题答案:

%e /usr/bin/time格式为:

进程使用的实际经过时间(墙上时钟),以秒为单位。

要使用抑制的stdout / stderr运行子进程并获取经过的时间:

#!/usr/bin/env python
import os
import time
from subprocess import check_call, STDOUT

DEVNULL = open(os.devnull, 'wb', 0)

start = time.time()
check_call(['sleep', '1'], stdout=DEVNULL, stderr=STDOUT)
print("{:.3f} seconds".format(time.time() - start))

timeit.default_timertime.time在Python
2上的POSIX上使用的,因此您应该有一个有效的时间,除非您的使用timeit不正确。

resource模块返回的信息 包括“实时”时间,但是您可以使用它来获取“用户”和“ sys”时间,即
“进程在用户模式下花费的CPU秒总数”。“进程在内核模式下花费的CPU秒总数”。 相应地:

#!/usr/bin/env python
import os
import time
from subprocess import Popen, STDOUT

DEVNULL = open(os.devnull, 'wb', 0)

start = time.time()
p = Popen(['sleep', '1'], stdout=DEVNULL, stderr=STDOUT)
ru = os.wait4(p.pid, 0)[2]
elapsed = time.time() - start
print(" {:.3f}real {:.3f}user {:.3f}system".format(
       elapsed, ru.ru_utime, ru.ru_stime))

您可以使用 子进程 以可移植的方式 运行子进程并运行 其他信息(cpu,内存,网络连接,线程,fds, 子进程等)
psutil.Popen获取 子进程

为了进行测试(以确保time.time()基于解决方案的结果相同),您可以捕获/usr/bin/time输出:

#!/usr/bin/env python
import os
from collections import deque
from subprocess import Popen, PIPE

DEVNULL = open(os.devnull, 'wb', 0)

time_lines_count = 1 # how many lines /usr/bin/time produces
p = Popen(['/usr/bin/time', '--format=%e seconds'] + 
          ['sleep', '1'], stdout=DEVNULL, stderr=PIPE)
with p.stderr:
    q = deque(iter(p.stderr.readline, b''), maxlen=time_lines_count)
rc = p.wait()
print(b''.join(q).decode().strip())

或将-o选项与命名管道一起使用:

#!/usr/bin/env python
import os
from contextlib import contextmanager
from shutil     import rmtree
from subprocess import Popen, STDOUT
from tempfile   import mkdtemp

DEVNULL = open(os.devnull, 'wb', 0)

@contextmanager
def named_pipe():
    dirname = mkdtemp()
    try:
        path = os.path.join(dirname, 'named_pipe')
        os.mkfifo(path)
        yield path
    finally:
        rmtree(dirname)

with named_pipe() as path:
    p = Popen(['/usr/bin/time', '--format=%e seconds', '-o', path] + 
              ['sleep', '1'], stdout=DEVNULL, stderr=STDOUT)
    with open(path) as file:
        time_output = file.read().strip()
    rc = p.wait()
print(time_output)


 类似资料:
  • 问题内容: 说我有一个下面的函数,如何捕获Process.spawn调用的输出?如果花费的时间超过指定的超时时间,我也应该能够终止该过程。 请注意,该功能还必须是跨平台的(Windows / Linux)。 谢谢。 问题答案: 您可以使用并告诉使用重定向的输出,而无需外部gem。 当然,仅从Ruby 1.9.2开始(我个人建议1.9.3) 以下是Spinach BDD在内部用于捕获输出和err输出

  • 我试图创建一个随机数生成器程序,跟踪玩家的胜利,损失,获胜百分比和总奖金。该程序的逻辑是,玩家每节获得3次机会,计算机生成一个随机数,玩家需要猜测或者更确切地说应该匹配。 我试过用如果 如果您对此有任何意见,我们将不胜感激。 游戏类别:

  • 问题内容: 我正在做漂亮的汤。我有一个html字符串: 我如何检索“获取此”,而忽略“ 忽略此 ” 谢谢 问题答案: 您可以获取文本,而不必递归检索子文本: 这与文本相对于孩子的位置无关:

  • 问题内容: 我试图用Python编写程序,并被告知运行.exe文件。运行此.exe文件时,它会吐出大量数据,并且我需要在屏幕上打印出一定的行。我很确定我需要使用或类似的东西,但是我是子处理的新手,没有任何线索。有人有简单的方法让我完成此工作吗? 问题答案: 像这样:

  • 问题内容: 在Linux下的python 2.6中,我可以使用以下命令来处理TERM信号: 除了仅一次设置一个信号,是否可以为该过程接收的所有信号设置处理程序? 问题答案: 您可以循环浏览信号模块中的信号并进行设置。

  • 问题内容: 我有一个程序可以执行为 这将安装一堆东西,并且屏幕上发生了很多活动。 现在,我正在尝试通过执行 希望所有发生在屏幕上的活动都被捕获在(或)中。但是,在进程运行时,内容直接打印到终端,而不会捕获到或中,在进程运行后,它们都为空。 这里会发生什么?如何捕获此内容? 问题答案: 通常,您所做的已经足以将所有输出传递到变量。 一个例外是,如果您正在运行的程序用于直接连接到其控制终端,并通过该终