返回输出之前,Python子进程在后台运行
问题内容:
我有一些要使用perf调试的Python代码。为此,我想使用子过程。以下命令返回进程的指令相关信息,直到通过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”行要做什么以终止该过程并检查输出。任何想法/帮助表示赞赏。
欢呼和感谢,
问题答案:
首先:我建议不要perf
在您的python进程中进行调用(如您在下面的任务的复杂性中所看到的),而是使用从命令行进行:
sudo perf stat -- python test.py
如果您 真的 想从python中调用perf,那么您将面临一些棘手的问题:
- 终止
perf
并使其输出收集的性能统计信息,您需要向其发送SIGINT
信号(尝试使用sudo perf stat -p mypid
:ctrl-\
将不打印任何内容,而ctrl-c
将打印) - 您需要捕获,
stderr
因为perf将其输出发送到stderr
(至少在我的版本中) - 您需要使用
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数据没有影响,唯一的影响是对“总运行时间”(*xx seconds time elapsed
)