4

这就是问题所在:有一组用不同语言(主要是 Perl 和 Python)编写的程序。每个程序都x从. 任务是编写这样的程序,给定并且将采样这样的行,这些行在计算上是最困难的。这个想法是在未来使用这些线路进行测试和基准测试。stdinstdoutfxstdinxx

这是我坚持的事情:f换行,从x读取一行,准备处理,传递到并立即开始收集关于 的静态信息。问题是我找不到任何可以区分计算难易行的指标。目前我尝试了两种方法:lstdinxlflxx

  1. /proc/[x pid]/stat在运行之间转储整个x. 它几乎不会改变(甚至 CPU 滴答声)。
  2. 只需监视x状态(使用相同的/proc/[x pid]/stat)并尝试测量它运行的时间。行之间没有区别。

也许有一些高精度的指标?像运行的 CPU 命令数或使用的内存中的字节数一样?

这是我用 Python 编写的实际代码,它充满了细节,所以我认为这是阅读它的最后一件事https://gist.github.com/alexanderkuk/5630079#file-f-py

4

1 回答 1

1

你的代码有很多问题。首先,这个:

def command_is_running(pid):
    with open('/proc/%d/stat' % pid) as stat:
        stats = stat.read()
        return ' R ' in stats

def wait_command_processes_line(pid):
    # stats = ...
    while command_is_running(pid):
      # stats = update_stats(stats, pid)
    return stats

是一个繁忙的循环。它会吃掉尽可能多的 CPU,.../stat反复读取直到R消失。当您尝试获得 CPU 使用的准确时间时,运行额外的 CPU 占用进程并不是一个好主意。

在另一个进程的运行状态发生变化之前,我不知道有什么方法可以让一个进程进入睡眠状态,所以我无法为繁忙的循环提供有效的替代方案。但这并不重要,因为第二个问题:进程状态并不像您希望的那样可预测。

您已经假设该进程将在您将一些数据写入其管道的那一刻变得可运行,并且将在处理该输入的持续时间内保持可运行状态。很难保证这是真的。您已经说过“磁盘 IO 很少见”,但您必须做得更好并完全消除它,包括页面错误。这很难,你可能还没有做到。所以我认为你的问题不是/proc/PID/stat包含错误的信息,而是你在错误的时间阅读它。

您可以通过将D状态视为与R. 但它看起来仍然很笨拙。

与其查看进程的可运行性,不如找到一个更好的指标,表明子进程已完成对最近输入行的处理。你说它“可能会打印一些东西到标准输出”。如果您可以安排它始终为每个输入行打印一些内容到标准输出,那么父进程可以等待该输出并在子进程出现时对子进程的 CPU 使用情况进行采样。

如果您无法让子进程为每个输入行提供完成的外部指示,则另一种方法可能是在尝试读取下一个输入行时考虑使用输入行完成。基本上,您将习惯于ptrace实现一个专门的类似strace实用程序,记录read输入管道上 s 的时间,仅在您的跟踪告诉您它正在尝试读取之后才将一行写入管道。

也许你甚至可以使用strace一些聪明的 shell 脚本来做到这一点。

这个想法的另一个变体是gdb在子进程的输入处理循环开始时设置一个断点,并设置一个脚本在每次断点被命中时运行。该脚本将收集计时信息,将下一行写入管道,然后执行 gdb cont

于 2013-05-25T21:07:06.357 回答