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,那么您将面临一些棘手的问题:
- 终止
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 数据几乎没有影响,它唯一的影响是 "total runtime" (*xx seconds time elapsed
)
我有一些 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,那么您将面临一些棘手的问题:
- 终止
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 数据几乎没有影响,它唯一的影响是 "total runtime" (*xx seconds time elapsed
)