Python中process.kill()无法终止目标进程的问题排查
问题原因
你使用了shell=True,此时subprocess.Popen启动的是shell进程,而你的目标程序./Process是这个shell的子进程。调用process.kill()只会终止shell进程,但它的子进程会变成孤儿进程被系统接管,继续运行,所以你看不到进程被终止的效果。
解决方案
方案1:移除shell=True(推荐)
直接启动目标进程,不需要通过shell中转,这样process就是./Process本身,kill()能直接终止它:
def monitor_process(process, file): while True: outline = process.stdout.readline().decode() if not outline: # 进程退出时readline返回空字符串,终止循环 break file.write(outline) file.flush() if "error" in outline: file.write("stdout: Error encountered. Exiting process.\n") file.flush() process.kill() break def runProcess(flight_path): output_file = flight_path + "/Process_terminal.log" with open(output_file, "w") as file: os.chdir("./build") # 去掉shell=True,用列表形式传入命令 process = subprocess.Popen(["./Process"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output_thread = threading.Thread(target=monitor_process, args=(process, file)) output_thread.start() process.wait() output_thread.join()
方案2:保留shell=True时杀掉整个进程组
如果必须用shell(比如需要shell的管道、通配符等特性),需要杀掉shell所在的整个进程组,确保子进程也被终止:
import os import signal def monitor_process(process, file): while True: outline = process.stdout.readline().decode() if not outline: break file.write(outline) file.flush() if "error" in outline: file.write("stdout: Error encountered. Exiting process.\n") file.flush() try: # 获取进程组ID,杀掉整个组 os.killpg(os.getpgid(process.pid), signal.SIGKILL) except ProcessLookupError: # 进程可能已经退出,忽略异常 pass break def runProcess(flight_path): output_file = flight_path + "/Process_terminal.log" with open(output_file, "w") as file: os.chdir("./build") command = "./Process" process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output_thread = threading.Thread(target=monitor_process, args=(process, file)) output_thread.start() process.wait() output_thread.join()
额外优化点
- 原代码中
if process.stdout:判断多余,因为你已经指定了stdout=subprocess.PIPE,process.stdout必然存在 - 可以把
"error"判断改成大小写不敏感的"error" in outline.lower(),避免漏判大写的ERROR os.chdir("./build")如果目录不存在会报错,建议提前检查目录是否存在:if not os.path.exists("./build"): raise FileNotFoundError("Build directory not found")
内容的提问来源于stack exchange,提问作者MsA
相关产品推荐
相关产品推荐

