簡體   English   中英

QProcess :: kill()不會殺死Linux中的孩子

[英]QProcess::kill() does not kill children in linux

我使用QProcess在服務器上進行冗長的計算。 只要我自己完成,它可能只需要幾秒鍾或幾個小時,就可以正常工作。 但是,我需要有可能在進程完成之前終止該進程,該進程僅在Windows機器上可以正常運行。

在linux中,我的QProcessQProcess ,對數據的處理成功執行,但是由它產生的子進程仍然保留。 這是我的代碼的摘錄:

// 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。 如前所述,它們可以生存。 是否有任何與平台無關的方法來殺死這些對象?

user4419802使我走上了正確的軌道。 在Linux中,殺死進程不會殺死其子進程。 他們被上移並繼續生活而不再有父母。

通常,您希望在pids子代時保存所有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進程輸出是一種簡單的轉換。

QProcess::kill()只是SIGKILL 因此,這與Qt無關,而與Unix進程管理有關。

您可以閱讀有關該問題的信息如何在父級退出后使子進程死亡?

最初的想法是@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());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM