我有以下问题:
我有一个Qt GUI应用程序(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.
    

    最佳答案

    我假设您运行某些UNIX系统(因为shell和/路径分隔符)。

    您是否真的需要两个进程(shell和Java)?也许只留下java将解决您的问题。将exec添加到您的脚本中:

    #!/bin/csh
    exec java -jar i2exrep.jar
    

    我的猜测是,当您在终端中运行应用程序然后关闭它时,所有子进程都会收到SIGHUP,因为它们失去了控制终端。从GUI应用程序运行脚本时,首先没有控制终端,因此Java不会在退出时终止。无论如何,终止子进程的正确方法是向其发送一个信号(SIGTERM,或者一段时间后可能是SIGKILL),然后等待(2)终止。

    如果您不想摆脱流程链中的Shell流程,请参阅this answer以了解如何将信号转发到Shell中的子流程。

    关于c++ - 终止QProcess不会杀死子进程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52931974/

    10-13 08:09