系统相关
首页 > 系统相关> > Qt启动子进程,子进程关闭时通知主进程,实现主进程对子进程的管理

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();

 

标签:insert,const,Qt,QProcess,QString,进程,processMap,启动子
来源: https://www.cnblogs.com/bclshuai/p/13574261.html