我正在使用此 Python 代码来运行 C++ 可执行文件:
import os
import subprocess
import signal
import time
def trench():
return subprocess.Popen(
['sudo', './Trench.out'],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT,
)
trench_display = trench()
time.sleep(5)
os.kill(trench_display.pid, signal.SIGINT)
我也尝试过这个,但似乎没有什么区别:
trench_display.send_signal(signal.SIGINT)
问题是当Python代码结束时,C++可执行文件继续运行。如果我输入任何命令并按 Enter 键,终端就会出现故障,并且程序似乎无法正常退出。
但是,如果我直接从终端执行它并使用
kill -2 PID
或 Ctrl + C
,它会正常退出。所以,我认为问题出在Python的子进程上。
我知道这是Python子进程的一个怪癖,但我想知道是否有办法修复它,而不修改C++源代码?
一个显而易见的答案是:只需运行
subprocess.popen
即可运行 sudo kill ...
,就像您一开始启动该过程一样。您的进程直接进行的系统调用将永远没有权限杀死更高特权的子进程。
虽然在现实世界中,您可以通过更新权限来解决此问题,使
sudo
不再需要执行 i2c 操作(这当然是解决此问题的最佳方法!),但这里有一种替代方法,适合以下范围:问题:
import os
import subprocess
import signal
import time
def trench():
p1 = subprocess.Popen(
['sudo', './Trench.out'],
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
p2 = subprocess.Popen(['cat'], stdin=p1.stdout)
p1.stdout.close()
return p2
trench_display = trench()
time.sleep(5)
trench_display.send_signal(signal.SIGTERM)
请注意,
trench_display
不再引用sudo ./Trench.out
,而是引用cat
,因此当你杀死它时,下次Trench.out
尝试写入其stderr时,它将收到EPIPE错误和SIGPIPE信号;除非它明确地尝试忽略这两件事,否则即使 Trench 以更高权限的用户身份运行,这也会导致 Trench 退出。
您当然可以编写Python代码从
p1.stdout
复制到Python项目的标准输出——使用cat
是保持这个答案简短的一种作弊方式。 :)