Pythonsubprocess在返回输出之前在后台运行

我有一些我想用perf进行debugging的Python代码。 为此,我想使用subprocess。 以下命令返回进程的指令相关信息,直到通过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'行中要做些什么来终止进程并检查输出。 任何想法/帮助表示赞赏。

欢呼声和感谢提前,

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

 sudo perf stat -- python test.py 

如果你真的想在Python中调用perf,那么你将面临一些棘手的问题:

  1. 终止性能和输出收集的性能统计信息,你需要发送SIGINT信号(试用sudo perf stat -p mypidctrl-\将不会打印,而ctrl-c会)
  2. 你需要捕捉stderr作为perf发送它的输出到stderr (至少在我的版本)
  3. 您需要使用fork() ,其中一个进程发送SIGINT ,另一个读取输出,同时进程终止。 没有分叉它不会工作,因为在SIGINT ed perf过程之后,不能再从标准输入读取,因为进程已经离开了,而且当你从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数据几乎没有影响,唯一的影响是对“总运行时间”( *xx seconds time elapsed

使用subprocess.Popen来运行perf 。 然后,使用pipe.communicate()发送输入并获取进程的输出。

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

例如:

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