2015-03-03 49 views
0

我使用QProcess在服務器上進行冗長的計算。只要我自己完成,它可能只需要幾秒鐘或幾個小時,並且工作正常。但是,我需要有可能在完成之前終止進程,這隻能在我的Windows機器上正常工作。QProcess :: kill()不會在linux中終止子節點

在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.所以我希望所有的這些被殺害的時候我殺了我的。如所述,他們生存下來是否有任何平臺無關的方式來殺死這些?

回答

0

user4419802給我帶來了正確的軌道上。在Linux中,殺死一個進程並不會殺死它的子進程。他們被提升並繼續,而不再有父母。

通常你想保存所有pids孩子產卵時(並有多個答案告訴你如何這樣做),但這是不可能的在我的情況下,因爲我不產卵的孩子,但外部應用程序我打電話沒有我的知識。於是我想出了以下解決方案,爲我的作品好:

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

// linux: a child is spawned which isnot 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過程輸出的解析是一個簡單的演員。

+0

更清晰的解決方案是在產卵時保存孩子的PID,而不是解析'ps'輸出。無論如何,你的代碼依賴於操作系統('ps --ppid' - GNU only?)。 – Matt 2015-03-19 08:53:22

+0

這將是更清潔,但它不是我的代碼產生的孩子。我只是開始一個外部程序,在某種程度上,這個程序會在我不知情的情況下產生孩子。 'ps --ppid'在[unix manpages]上(http://unixhelp.ed.ac.uk/CGI/man-cgi?ps),所以我期望它能在Linux上運行。並不需要在我的情況下爲Windows – Bowdzone 2015-03-19 09:04:13

+0

我的意思是'--ppid'是GNU選項,所以它只適用於GNU/Linux。 BSD和Solaris等都不能工作。所以它很髒。 – Matt 2015-03-19 09:14:12