【发布时间】:2019-06-05 03:30:35
【问题描述】:
我有以下问题: 我有一个 Qt GUI-Application (c++),它通过 bash 脚本启动一个外部 java 应用程序。当我终止我的 QProcess 时,脚本被杀死,但子进程(java 应用程序)仍在运行。
我不理解这种行为,因为如果我在终端中运行脚本并杀死它,子进程也会被杀死。可能和Qt中的各种事件循环有关,我还没弄明白。
这是我的代码:
MainWindow.h
#include <QMainWindow>
#include <QProcess>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void slot_startQProcess();
void slot_killQProcess();
private:
Ui::MainWindow *ui;
QProcess myProcess;
};
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pb_start, &QPushButton::clicked, this, &MainWindow::slot_startQProcess);
connect(ui->pb_kill, &QPushButton::clicked, this, &MainWindow::slot_killQProcess);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slot_startQProcess()
{
myProcess.setWorkingDirectory("./i2exrep");
myProcess.start("./myScript.sh");
}
void MainWindow::slot_killQProcess()
{
myProcess.close();
}
main.cpp
#include "MainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
myScript.sh
#!/bin/csh
java -jar i2exrep.jar
文件夹结构:
- .pro 文件
- *.cpp
- *.h
- i2exrep(文件夹)
- myScript.sh
所以我的应用程序启动“myScript.sh”,它启动“java -jar i2exrep.jar”
杀死 QProcess 只会终止“myScript.sh”,但“java -jar i2exrep.jar”仍在运行。 - i2exrep.jar
编辑:
我尝试了另一个主函数:
#include <QCoreApplication>
#include <QProcess>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QProcess myProcess;
myProcess.setWorkingDirectory("./i2exrep");
myProcess.start("./myScript.sh");
return a.exec();
}
当我退出这个程序时,Java 应用程序也会终止。当我完成第一个程序(GUI 应用程序)时,只有脚本被终止,Java 应用程序继续运行。我收到以下错误消息:
QProcess: Destroyed while process ("./myScript.sh") is still running.
【问题讨论】:
-
您是否在关闭前尝试使用
QProcess::kill或QProcess::terminate? (发送后您必须稍等片刻才能真正退出。使用QProcess::waitForFinished这样做) -
我的猜测是 myScript.sh 正在启动分离的 i2exrep.jar,因此它可以在生成过程终止后运行。
-
@Felix:我将插槽编辑如下:
void MainWindow::slot_killQProcess() { myProcess.kill(); myProcess.terminate(); myProcess.waitForFinished(1000); myProcess.close(); }调用该方法仍然只停止脚本。 Java 应用程序仍在运行。 -
@Mike 这也是我的猜测。但是如何防止 Java 应用程序分离运行呢?我想将 Java 应用程序“链接”到父进程 myScript.sh.
-
你
kill(SIGKILL) 直接进程,所以terminate(SIGTERM) 和close(关闭/关闭流) 无效。你应该只terminate它