Reputation: 271
I have the following Problem: I have a Qt GUI-Application (c++) which starts an external java application via a bash-script. When I terminate my QProcess the script is killed, but the child-process (the java-application) is still running.
I don't understand this behavior, because if I run the script in terminal and kill it, the child process is also killed. Maybe it has something to do with the various event loops in Qt, which I have not understood yet.
Here is my code:
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
Folder structure:
So my application starts "myScript.sh" which starts "java -jar i2exrep.jar"
Killing the QProcess only terminates "myScript.sh", but "java -jar i2exrep.jar" is still running. - i2exrep.jar
EDIT:
I tried the same with another main function:
#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();
}
When I quit this program, then the Java application is also terminated. When I finish the first program (the GUI application), then only the script is terminated and the Java application continues to run. I get the following error message:
QProcess: Destroyed while process ("./myScript.sh") is still running.
Upvotes: 1
Views: 1793
Reputation: 11
I solved it by using setsid
to start the process.
Please, check the example below:
process->start("setsid ./example.sh");
(...)
QString killingProcess = "kill -TERM -" + QString::number(process->pid());
system(killingProcess.toStdString().c_str());
For more details, please, visit this link.
Upvotes: 1
Reputation: 5289
I assume you run some UNIX system (since the shell and /
path separator).
Do you really need both processes (the shell and java)? Maybe leaving only java will solve your problem. Add exec
to your script:
#!/bin/csh
exec java -jar i2exrep.jar
My guess is that when you run your application in a terminal and then close it, all child processes receive SIGHUP since they lose the controlling terminal. When you run the script from GUI application there is no controlling terminal at the first place, so java won't terminate on quit. Anyway, the correct way to terminate a child process is to send it a signal (SIGTERM, maybe SIGKILL after some time) and then wait(2) it's termination.
If you don't want to get rid from a shell process in your process chain, see this answer to find out how to forward signals to child process in shell.
Upvotes: 1