确保终止其父QThread时终止QProcess

时间:2012-07-10 11:53:56

标签: multithreading qt

我在Qt中编写代码,我使用多个线程(Qthreads)以下面的代码片段中显示的方式启动命令行进程:

void test_streamer_thread::run()
{
    QProcess    start_process;
    ...

    ret_status = start_process.execute("some_cmd.exe",some_args);
    start_process.close();
}

一旦启动,该过程将无限进行(在Windows任务管理器中显示为单独的进程)。但是,当应用程序终止时,该过程仍然存在。如何确保此过程在启动应用程序的终止时终止。

2 个答案:

答案 0 :(得分:3)

使用单独的线程来启动进程是完全没必要的。

确保在应用程序终止时终止子进程的最简单方法是

QProcess * p = new QProcess(....);
connect(qApp, SIGNAL(aboutToQuit()), process, SLOT(terminate()));

请参阅下面的完整示例。

这种误解正在蔓延,就像疾病一样,线程可以解决每个人的问题。我的观察是,在10个帖子中有9个Qt标签,线程的使用是不必要的,是不理解问题的结果。

我的规则是:如果你认为你需要使用线程,试着解释它,如果只是在你的脑海里,说服你的同事。执行此操作后,请检查您引用的所有事实以支持您的论证实际上是正确的。在许多情况下,他们不是。

下面的示例代码没有捕获Unix信号,因此 - 正如您在Linux和OS X上所注意到的那样 - 它只会终止直接后代进程,而不会终止可能从它启动的任何后续进程。你可以need to handle Unix signals来解决这个问题。

//main.cpp
#include <QApplication>
#include <QPushButton>
#include <QProcess>

class Launcher : public QObject
{
    Q_OBJECT
    int n;
    QProcess * process;
signals:
    void setDisabled(bool);
public slots:
    void launch() {
        QStringList args;
        args << QString::number(n);
        process = new QProcess(this);
        process->start(QCoreApplication::applicationFilePath(), args);
        connect(qApp, SIGNAL(aboutToQuit()), process, SLOT(terminate()));
        emit setDisabled(true);
    }
public:
    Launcher(int no) : n(no), process(0) {}
    ~Launcher() {
        if (process) {
            process->terminate();
            process->waitForFinished();
        }
    }
};

int main(int argc, char ** argv)
{
    QApplication a(argc, argv);
    int n = 0;
    if (argc > 1) n = QByteArray(argv[1]).toInt();
    Launcher launcher(n+1);
    QPushButton spawn(QString("Spawn #%1").arg(n));
    launcher.connect(&spawn, SIGNAL(clicked()), SLOT(launch()));
    spawn.connect(&launcher, SIGNAL(setDisabled(bool)), SLOT(setDisabled(bool)));
    spawn.show();
    return a.exec();
}

#include "main.moc"

答案 1 :(得分:0)

看起来你要求一个单独的进程,而不是创建线程。

如果它是一个单独的进程,那么您将需要父进程和子进程(可能是管道或信号)之间的某种通信来进行通信,它应该退出。

如果是线程,则在终止进程后,所有线程都会死掉。此外,您不会在Windows任务管理器中将线程视为单独的进程(不确定它们将如何显示,但它们不会显示为线程)。