Python 在返回输出之前在后台进行子处理 运行

Python subprocess running in background before returning output

我有一些 Python 代码想用 perf 调试。为此,我想使用子流程。下面的命令returns指令相关的一个进程的信息,直到通过Ctrl^C退出命令。

perf stat -p <my_pid>

现在,我想 运行 在后台的 Python 代码中执行此操作,直到我希望能够终止其操作并打印命令输出的某个时刻。为了表明我的意思:

x = subprocess.call(["perf","stat","-p",str(GetMyProcessID())])

.. CODE TO DEBUG ..

print x   # I want to terminate subprocess here and output 'x'

现在,我想确定在 'print x' 行要做什么来终止进程并检查输出。 任何 idea/help 表示赞赏。

提前干杯和感谢,

使用subprocess.Popen to run perf. Then, use pipe.communicate()发送输入并获取进程的输出。

完成后,调用 pipe.terminate() 终止进程。

例如:

pipe = subprocess.Popen(["perf","stat","-p",str(GetMyProcessID())], stdout=PIPE)

pipe.terminate()
stdout, stderr = pipe.communicate()
print stdout

首先:我建议不要从您的 python 进程中调用 perf(正如您在下面任务的复杂性中看到的那样),而是从命令行使用:

sudo perf stat -- python test.py

如果您真的想从 python 中调用 perf,那么您将面临一些棘手的问题:

  1. 终止 perf 并使其输出收集的性能统计数据,您需要向它发送 SIGINT 信号(用 sudo perf stat -p mypid 试试: ctrl-\ 将打印没什么,而 ctrl-c 会)
  2. 您需要捕获 stderr,因为 perf 将其输出发送到 stderr(至少在我的版本中)
  3. 您需要使用 fork(),其中一个进程发送 SIGINT,而另一个进程在进程结束时读取它的输出。如果没有 fork,它将无法工作,因为在你 SIGINT 编辑了 perf 进程后,你无法再从 stdin 读取,因为进程已经消失,当你首先从 stdin 读取时,你赢了在 perf 正确终止之前不会得到任何输出。

这意味着您最终会得到这个 python 程序:

import subprocess
import os
import signal
import time

perf = subprocess.Popen(['perf', 'stat',  '-p', str(os.getpid())], stderr=subprocess.PIPE)

# <-- your code goes here

if os.fork() == 0:
    # child
    time.sleep(1)  # wait until parent runs `stderr.read()`
    perf.send_signal(signal.SIGINT)
    exit(0)

# parent
print("got perf stats>>{}<<".format(perf.stderr.read().decode("utf-8")))

time.sleep(1) 位很难看,它会做什么,但我想它会在 99% 的情况下起作用。它对 perf 数据几乎没有影响,它唯一的影响是 "total runtime" (*xx seconds time elapsed)