QProcess :: kill()不会杀死linux中的子进程

时间:2015-03-03 10:59:24

标签: c++ qt process

我使用QProcess在服务器上进行冗长的计算。它可能只需要几秒钟或几个小时,只要我让它自己完成就可以正常工作。但是,我需要有可能在它完成之前终止进程,这只能在我的Windows机器上运行。

在linux中,我的QProcess被杀死,我的数据处理成功执行,但由它产生的子进程仍然存在。以下是我的代码的摘录:

// constructor
server::server(QObject* parent) : QTcpServer(parent)
{
    this->calc_proc = new QProcess(this);
    QObject::connect(this->calc_proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(calc_finished(int,QProcess::ExitStatus)));

    ...
}

void server::start_job(){

    QString working_directory = "...";
    QString input_file = "...";
    QStringList arguments;
    arguments << "memory=max" << "batch=no" << input_file;

    this->calc_proc->setWorkingDirectory(working_directory);
    this->calc_proc->start("path_to_external_program", arguments);

    qDebug() << "Calc started with pid: " << this->calc_proc->pid();
}

void server::kill_job(){

    this->calc_proc->terminate();
    //this->calc_proc->kill();
}

使用terminate()kill()时,行为似乎没有差异。据我所知,子进程是我进程的子进程:

Calc started with pid:  26395

ps ax
...
26441 pts/0    S      0:00 time /msc/MSC_Nastran/20131/msc20131/linux64/analysis
26442 pts/0    Rl    16:59 /msc/MSC_Nastran/20131/msc20131/linux64/analysis
...

ps -p 26442 -o ppid=
26441

ps -p 26441 -o ppid=
26395

我的QProcess将他的pid作为26395返回,其中有一个孩子26441,其中有一个孩子26442.所以当我杀死我的时候,我预计所有这些都会被杀死。如上所述他们生存。是否还有任何与平台无关的方法来杀死这些?

3 个答案:

答案 0 :(得分:2)

QProcess::kill()只是SIGKILL。所以它不是关于Qt,而是关于Unix进程管理。

您可以阅读该问题How to make child process die after parent exits?

答案 1 :(得分:2)

user4419802让我走上了正确的轨道。在Linux中,杀死一个进程并不会杀死它的孩子。他们向上移动并继续而不再有父母。

一般来说,你想要在产生它们时保存所有pids个孩子(并且有多个答案告诉你如何这样做)但是在我的情况下这是不可能的,因为我没有产生孩子,但我打电话给我的外部应用程序,在我不知情的情所以我想出了以下对我有用的解决方案:

QProcess* main_process = new QProcess(this);
...

// linux: a child is spawned which is not killed with its parent
//        therefore the process id is retrieved and the process killed independently
#if defined(Q_OS_LINUX)
QProcess get_child_a;
QStringList get_child_a_cmd;
get_child_a_cmd << "--ppid" << QString::number(main_process->processId()) << "-o" << "pid" << "--no-heading";
get_child_a.start("ps", get_child_a_cmd);
get_child_a.waitForFinished(5000);
QString child_a_str = get_child_a.readAllStandardOutput();
int child_a = child_a_str.toInt();

QProcess::execute("kill " + QString::number(child_a));
#endif

// windows & linux: kill main process
main_process->kill();

就我而言,我知道只返回一个子进程id,因此解析get_child进程输出是一个简单的转换。

答案 2 :(得分:0)

向@Bowdzone表示最初的想法!

由于答案对我来说不是100%有用的,因为我的父母产生了多个子进程,所以我对该方法进行了一些调整:

void CameraReceiver::stopChildProcesses(qint64 parentProcessId) {
    qDebug() << "stopChildProcesses for parent id:" << parentProcessId;

    QProcess get_childs;
    QStringList get_childs_cmd;
    get_childs_cmd << "--ppid" << QString::number(parentProcessId) << "-o" << "pid" << "--no-heading";
    get_childs.start("ps", get_childs_cmd);
    get_childs.waitForFinished();
    QString childIds(get_childs.readAllStandardOutput());
    childIds.replace('\n', ' ');

    QProcess::execute("kill " + childIds);
}

然后我可以简单地调用以下内容:

stopChildProcesses(parentProcess.processId());
相关问题