Qt啟動子進程,子進程關閉時通知主進程,實現主進程對子進程的管理


自己開發了一個股票智能分析軟件,功能很強大,需要的點擊下面的鏈接獲取:

https://www.cnblogs.com/bclshuai/p/11380657.html

1.需求描述 

Qt主進程啟動之后,在啟動一個程序的四個子進程,子進程關閉時,會通過狀態改變信號,通知主進程的槽函數,實現刪除子進程的管理QProcess* 變量;

2.Qt進程QProcess介紹

2.1進程啟動方式

有兩種啟動方式,start是父子進程關聯啟動子進程。startDetached則是以分離的方式啟動進程。

   void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);

    void start(const QString &command, OpenMode mode = ReadWrite);

    void start(OpenMode mode = ReadWrite);

 

 static bool startDetached(const QString &program, const QStringList &arguments,    const QString &workingDirectory

    static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads

    static bool startDetached(const QString &command);

 

3.實現步驟

(1)創建QMap保存進程的QProcess* 變量;

QMap<int,QProcess*> m_processMap;

(2)主進程中獲取子進程路徑,通過for循環啟動四個子進程,並傳入命令行參數,同時將for循環的ii值作為map的key值,用於標記是哪個進程。綁定stateChanged信號槽,之前打算用finish信號,但是finish信號有個重載函數,所以使用connect連接時,&QProcess::finished,無法判斷是哪個函數,所以不行。如果用SIGNAL(finish(int exitCode)),又無法用SLOT去定義lamlar表達式。為了實現i序號作為進程的標識id,進程狀態改變時,觸發信號,可以定位到是哪個進程結束了,直接在map中刪除該進程變量。就可以了方便實現主進程和子進程之間的管理

void finished(int exitCode); // ### Qt 6: merge the two signals with a default value

    void finished(int exitCode, QProcess::ExitStatus exitStatus)

 

QString strProcessPath = QDir::currentPath() + "/AlgAnalyizeTool/AlgAnalyizeTool.exe";//AlgAnalyizeTool.exe
    if (!QFile(strProcessPath).exists())
    {
        QMessageBox::information(NULL, "提示", "分析進程不存在", QMessageBox::Yes, QMessageBox::Yes);
        return;
    }
    for (int i = 0; i < 4; i++)
    {
        QJsonObject jsonMain;
        QJsonObject serverConf;
        QJsonObject videoAnalyizeConf;
        videoAnalyizeConf.insert("cpuCores", 4);
        videoAnalyizeConf.insert("gpuNo", i);
        videoAnalyizeConf.insert("threadCount", 4);
        serverConf.insert("ip", "10.25.106.103");
        serverConf.insert("port", 8011);
        serverConf.insert("sessionId", QString::number(i));
        jsonMain.insert("serverConf", serverConf);
        jsonMain.insert("videoAnalyizeConf", videoAnalyizeConf);
        QJsonDocument root_Doc;
        root_Doc.setObject(jsonMain);
        QByteArray root_str = root_Doc.toJson(QJsonDocument::Compact);  //緊湊格式                                                            //    QByteArray root_str = root_Doc.toJson(QJsonDocument::Indented);   //標准JSON格式    QString strJson(root_str);
        
        QString strJson((root_str.toBase64()));
        QStringList Qstringlist;
        Qstringlist << strJson;
        QProcess* process=new QProcess(this);
        connect(process,&QProcess::stateChanged, this, [=](QProcess::ProcessState state) { if (state== QProcess::ProcessState::NotRunning) { QMap<int, QProcess*>::iterator it = m_processMap.find(i); if (it != m_processMap.end()) { delete it.value(); m_processMap.erase(it); } } });
        LOG_TRACE("start  begin! ");
        process->start(strProcessPath, Qstringlist);
        m_processMap[i] = process;
        LOG_TRACE("start  end! ");
    }

 

4.注意事項

4.1.主進程退出前先關閉子進程並釋放資源

以start方式啟動的子進程,需要在主進程關閉的析構函數中關閉主進程,並且刪除new出的進程指針變量;才可以正常退出。否則,資源管理器中會保留主進程和子進程。導致程序無法覆蓋或編譯生成報錯。

QMap<int, QProcess*>::iterator it = m_processMap.begin();
    for (;it!=m_processMap.end();it++)
    {
        it.value()->terminate();
        delete it.value();
    }
    m_processMap.clear();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM