如何彻底终止QProcess启动的MPI程序?
解决QProcess启动MPI程序后无法彻底终止子进程的问题
问题原因
当你用QProcess启动mpiexec时,mpiexec会创建多个test_mpi.exe子进程。QProcess.kill()或terminate()仅会终止mpiexec父进程,但Windows系统默认不会自动终止父进程的子进程,导致test_mpi.exe残留。直接用taskkill /IM test_mpi.exe /F会杀掉所有同名进程,不符合需求。
解决方案
通过获取mpiexec的PID,使用taskkill命令的/PID(指定进程ID)和/T(终止进程树)参数,仅终止当前QProcess启动的mpiexec及其所有子进程。
修改后的代码
更新worker类(其余代码保持不变)
import sys from PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import pyqtSignal, QThread, QProcess from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QTextCursor class worker(QThread): logChange = pyqtSignal(str) def __init__(self): super().__init__() self.process = None self.mpiexec_pid = -1 self.stopFlag = False def run(self): self.process = QProcess() command = f"mpiexec -n 8 test_mpi.exe" self.process.start(command) # 等待进程启动并记录PID if self.process.waitForStarted(): self.mpiexec_pid = self.process.processId() self.logChange.emit(f"启动mpiexec,PID: {self.mpiexec_pid}\n") self.stopFlag = False while True: if self.stopFlag: self.logChange.emit("开始终止进程...\n") # 先尝试优雅终止 self.process.terminate() # 等待3秒,若未结束则强制终止进程树 if not self.process.waitForFinished(3000): if self.mpiexec_pid != -1: kill_proc = QProcess() kill_cmd = f"taskkill /PID {self.mpiexec_pid} /F /T" kill_proc.start(kill_cmd) kill_proc.waitForFinished() self.logChange.emit(f"已强制终止进程树,PID: {self.mpiexec_pid}\n") self.logChange.emit("STOP!\n") break if self.process.waitForReadyRead(1000): output = self.process.readAllStandardOutput() output = bytearray(output).decode("gbk") self.logChange.emit(output) else: QApplication.processEvents() if self.process.state() == QProcess.NotRunning: self.logChange.emit("FINISHED!\n") break def stop(self): self.stopFlag = True # Ui_Form和MyWidget代码与原代码一致,此处省略
关键说明
taskkill /PID {pid} /F /T参数解析:/PID:指定要终止的进程ID,确保只针对当前启动的mpiexec实例/F:强制终止进程,避免进程无响应时无法终止/T:终止指定进程及其所有子进程,彻底清理test_mpi.exe的残留实例
- 先尝试
terminate()优雅终止,再用taskkill强制清理,减少粗暴终止可能导致的资源泄漏 - 记录
mpiexec的PID,确保只操作当前启动的进程组,不会影响其他用户或程序启动的同名进程
内容的提问来源于stack exchange,提问作者SJ2050
相关产品推荐
相关产品推荐

