2012-07-10 60 views
0

我寫內的Qt我在哪裏使用多線程(Qthreads),以在下面的代碼段中所示的方式啓動的命令行的處理的代碼:其父終止確保QProcess中終止的QThread

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

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

啓動後,該過程將無限進行(在Windows任務管理器中顯示爲單獨的進程)。但是,當應用程序終止時,該過程仍然存在。如何確保此過程在終止啓動它的應用程序時終止。

問候,

SAURABH甘地

回答

0

看起來像你派生一個獨立的過程,而不是創建線程。

如果它是一個單獨的進程,那麼您將需要在父進程和子進程(可能是管道或信號)之間進行某種通信,以通知它應該退出。

如果它是線程,在殺死進程後,所有線程都會死亡。此外,你不會在Windows任務管理器中將線程看作單獨的進程(不確定它們將如何出現,但它們不會顯示爲線程)。

2

使用單獨的線程來啓動進程是完全沒有必要的。

確保子進程的最簡單方式被終止時,應用程序終止將

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

一個完整的例子見下文。

有這種誤解正在像疾病一樣蔓延,線索是解決所有人問題的方法。我的觀察結果是,在使用Qt標籤的10篇文章中,有9篇不需要使用線程,這是不理解問題的結果。

我的規則是:如果你認爲你需要使用線程,試着解釋它,如果只是在你的腦海中,說服你的同事。做完這件事後,檢查一下你引用的所有事實來支持你的觀點其實都是事實。在很多情況下,他們不是。

下面的示例代碼沒有捕獲到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"