多进程任务处理
在实际项目设计中,往往会遇到这样的情况:多条命令同时执行。这种情况下就需要针对进程进行合理调配,以达到预期效果.
模块设计
定义结构体列表来保存进程信息,结构体信息包含定义的进程、该进程需执行的命令、进程编号3个信息。
定义的进程:执行的进程,用以执行进程命令;
该进程需执行的命令:该命令是以字符串列表的形式定义,代表该进程下有哪些需要命令需要执行;
进程编号:对进程按添加的顺序进行编号,后续进程的执行,状态判断等均以此区分。
该设计的方式为默认的情况下,只存在一个公共进程,在创建对象时创建该端口的执行进程。进程在执行时以扫描进程的命令列表为判断,若命令列表存在未执行的命令,进程将执行该命令,因此通过添加进程的命令即可使该命令执行,执行完毕删除该命令,后续命令前移,因此可实现该进程下多指令的执行。为记录进程执行状态定义一个结构体数组保存数据,可根据进程编号获取其保存的信息。
为方便理解,下面以框图解释:
Model_Process.cpp
#include "Model_Process.h"
/**************************************************************************************************************************
* ***************功能描述:进程处理******************************************************************************************
* *********************(1)根据USB端口建立进程,进程的执行即是端口执行**********************************************************
* **********************(2)进程0为全局进程,可用来做全局命令执行,不参与USB升级操作**********************************************
* ***********************(3)命令执行建立了命令链表,可按链表执行连续操作:命令时间较长时不建议使用**********************************
**************************************************************************************************************************/
/*************************************************************
/函数功能:构造函数:开启定时器,建立全局进程0
/函数参数:无
/函数返回:无
*************************************************************/
Model_Process::Model_Process()
{
/*设置定时器*/
m_timerID1=startTimer(10);//刷新进程执行
/*建立全局进程-进程0*/
Process_Add();
}
/*************************************************************
/函数功能:析构函数:杀死定时器
/函数参数:无
/函数返回:无
*************************************************************/
Model_Process::~Model_Process()
{
killTimer(m_timerID1);
}
/*************************************************************
/函数功能:定时器事件:1.扫描执行进程;2.进程定时处理
/函数参数:event:定时器事件
/函数返回:无
*************************************************************/
void Model_Process::timerEvent(QTimerEvent *event)
{
if(!P_List.length())
return ;
if(event->timerId()==m_timerID1)
{
/*扫描执行进程*/
Process_Execute();
}
}
/*************************************************************
/函数功能:进程添加:根据设备端口添加进程:1~...
/函数参数:无
/函数返回:无
*************************************************************/
void Model_Process::Process_Add()
{
tProcess_t aProcess;
aProcess.process=new QProcess();
aProcess.cmdList.clear();
aProcess.pNum=P_List.length();
P_List.append(aProcess);
//cout<< P_List.length();
connect(P_List.at(P_List.length()-1).process,SIGNAL(readyRead()),this,SLOT(ProcessReadAll()));
connect(P_List.at(P_List.length()-1).process,SIGNAL(readyReadStandardError()),this,SLOT(ProcessReadError()));
connect(P_List.at(P_List.length()-1).process, SIGNAL(stateChanged(QProcess::ProcessState)),this, SLOT(ProcessshowState(QProcess::ProcessState)));
pParam[aProcess.pNum].isRun=noRun;
pParam[aProcess.pNum].rTime=0;
pParam[aProcess.pNum].pBarValue=0;
pParam[aProcess.pNum].CmdRead="";
pParam[aProcess.pNum].CmdError="";
}
/*************************************************************
/函数功能:进程添加:根据设备端口添加进程:1~...
/函数参数:Workpath:进程的工作路径
/函数返回:无
*************************************************************/
void Model_Process::Process_Add(QString Workpath)
{
Process_Add();
P_List.at(P_List.length()-1).process->setWorkingDirectory(Workpath);
}
/*************************************************************
/函数功能:进程运行目录跳转
/函数参数:无
/函数返回:true:正在运行 false:未运行
*************************************************************/
void Model_Process::ProcessPathJump(QString path)
{
for(uint8_t i=1;i<P_List.length();i++)
P_List.at(i).process->setWorkingDirectory(path);
}
/*************************************************************
/函数功能:进程删除
/函数参数:pNum:进程序号
/函数返回:无
/系统进程不可删除
*************************************************************/
void Model_Process::Process_Del(uint8_t pNum)
{
if((pNum>0)&&(pNum<P_List.length()))
{
tProcess_t tempProcess;
P_List.removeAt(pNum);
/*删除当前进程后,后面进程的序号修改*/
for(uint8_t i=pNum;i<P_List.length();i++)
{
tempProcess=P_List.at(i);
tempProcess.pNum=i;
P_List.replace(i,tempProcess);
}
}
else
cout << "pNum is Over or SYSProcess.";
}
/*************************************************************
/函数功能:进程执行:遍历进程列表,执行置开始标志,且有进程命令的进程
/函数参数:无
/函数返回:无
//Process.process->waitForFinished();//阻塞,直到上一个进程执行完,再进行下一个进程执行
*************************************************************/
void Model_Process::Process_Execute()
{
for(uint8_t i=0;i<P_List.length();i++)
{
/*进程开启了运行标志且进程命令不为空*/
if((pParam[i].isRun == RunStart) && (P_List.at(i).cmdList.isEmpty()==false))
{
QString cmdStr = P_List.at(i).cmdList.first();
ProcessOutDeal(i,"EXEC>>"+cmdStr);
P_List.at(i).process->start("cmd.exe", QStringList() << "/c" << cmdStr);
/*开启进程失败*/
if (P_List.at(i).process->waitForStarted()==false)
{
cout << i <<"WARN:Failed to start";
ProcessisOver(i);//进程结束
pParam[i].isRun=noRun;
}
}
}
}
/*************************************************************
/函数功能:进程开始执行:置进程运行标志位,添加进程执行命令
/函数参数:pNum:进程序号 cmdStr:命令字符串
/函数返回:无
*************************************************************/
void Model_Process::ProcessStart(uint8_t pNum,QString cmdStr)
{
if(pNum<P_List.length())
{
/*若进程未进行,启动运行,否则只添加指令列表*/
if(pParam[pNum].isRun == noRun)
pParam[pNum].isRun=RunStart;
/*进程只执行单个命令,带判断条件;
* 若执行多个命令,将判断添加去掉,累加即可*/
if(P_List.at(pNum).cmdList.isEmpty())
{
tProcess_t tempProcess=P_List.at(pNum);
tempProcess.cmdList.append(cmdStr);
P_List.replace(pNum,tempProcess);
}
}
else
cout << "pNum is Over.";
}
/*************************************************************
/函数功能:停止进程执行
/函数参数:devNum:进程号 appStr:命令
/函数返回:无
//备注:执行杀死进程的命令
adb -s 8495650c21bb13c shell "ps | grep logcat"
USER PID PPID VSIZE RSS WCHAN PC NAME
root 2797 1754 2452 1780 c00f7e34 400b6124 S logcat
adb -s 8495650c21bb13c shell kill -9 PID
*************************************************************/
void Model_Process::stopProcess(QString devNum,QString appStr)
{
//摘自ACCTool工具
QProcess process;
QString command;//"adb -s " + devNum + " shell ps | grep " +appStr;
if(devNum.isEmpty())
command = PSGREP(appStr);
else
command = PSGREP_S(devNum,appStr);
cout << (command);
process.start(command);
process.waitForStarted();
process.waitForFinished();
QByteArray byteArray = process.readAllStandardOutput();
QString str = QString::fromLocal8Bit(byteArray);
cout << (str);
QStringList list = str.simplified().split(" ");
for (int i=0;i<list.length();i++)
{
if(i%9 == 1){
QString killcmd ;//"adb -s " + devNum + " shell kill -9 " + list.at(i);
if(devNum.isEmpty())
killcmd = KILL_9(list.at(i));
else
killcmd = KILL_9_S(devNum,list.at(i));
cout << (killcmd);
process.start(killcmd);
process.waitForStarted();
process.waitForFinished();
QByteArray byteArray = process.readAllStandardOutput();
QString str = QString::fromLocal8Bit(byteArray);
cout << (str);
}
}
process.close();
}
/*************************************************************
/函数功能:进程读信息槽函数
/函数参数:无
/函数返回:无
*************************************************************/
void Model_Process::ProcessReadAll()
{
if(!P_List.length())
return ;
QObject *sender = QObject::sender();
for(uint8_t i=0;i<P_List.length();i++)
{
if(sender==P_List.at(i).process)
{
ProcessOutDeal(i,"Out>>"+P_List.at(i).process->readAll());//QString::fromLocal8Bit();//any:最新版本的QT无需转换,可直接输出中文
break;
}
}
}
/*************************************************************
/函数功能:进程读错误信息槽函数
/函数参数:无
/函数返回:无
*************************************************************/
void Model_Process::ProcessReadError()
{
if(!P_List.length())
return ;
QObject *sender = QObject::sender();
for(uint8_t i=0;i<P_List.length();i++)
{
if(sender==P_List.at(i).process)
{
ProcessOutDeal(i,"Error>>"+QString::fromLocal8Bit(P_List.at(i).process->readAllStandardError()));
break;
}
}
}
/*************************************************************
/函数功能:进程判断状态槽函数
/函数参数:state:进程状态:Running-正在运行 Starting-开始运行 NotRunning-运行结束
/函数返回:无
*************************************************************/
void Model_Process::ProcessshowState(QProcess::ProcessState state)
{
if(!P_List.length())
return ;
QObject *sender = QObject::sender();
/*遍历进程*/
for(uint8_t i=0;i<P_List.length();i++)
{
/*确认执行的进程*/
if(sender == P_List.at(i).process)
{
switch(state)
{
case QProcess::Running:/*进程正在执行*/
{
pParam[i].isRun=Runing;
}
break;
case QProcess::Starting:/*进程开始执行*/
{
pParam[i].rTime=1;
pParam[i].pBarValue=1;
ProcessBar(i-1,pParam[i].pBarValue,GREEN);
}
break;
case QProcess::NotRunning:/*进程结束执行*/
{
/*计时清空*/
pParam[i].rTime=0;
/*删除执行过的命令*/
tProcess_t tempProcess=P_List.at(i);
tempProcess.cmdList.removeFirst();
P_List.replace(i,tempProcess);
/*进程执行完毕,仍有命令,继续开启进程执行下一个命令*/
if(P_List.at(i).cmdList.isEmpty()==false)
pParam[i].isRun=RunStart;
else
{
pParam[i].isRun=noRun;//先转换进程执行状态,再去处理进程结束
ProcessisOver(i);//进程结束
}
}
break;
}
break;
}
}
}
/*************************************************************
/函数功能:获得某一进程运行状态
/函数参数:pNum:进程序号
/函数返回:sRun_e:进程状态
*************************************************************/
sRun_e Model_Process::GetProcessRunStatus(uint8_t pNum)
{
return pParam[pNum].isRun;
}
/*************************************************************
/函数功能:是否有进程正在运行
/函数参数:无
/函数返回:true:正在运行 false:未运行
*************************************************************/
bool Model_Process::GetProcessIsRun()
{
for(uint16_t i=P_List.length();i>0;i--)
{
if(pParam[i].isRun != noRun)
{
return true;
}
}
return false;
}
Model_process.h
#ifndef MODEL_PROCESS_H
#define MODEL_PROCESS_H
#include <QDebug>
#include <QProcess>
#include <QTimerEvent>
#include <QFileDialog>
#include <QTime>
#include "model_include.h"
#define P_Max 128
/*************************************************************
/运行状态
/noRun:无运行
/RunStart:开始运行
/Runing:正在运行
/RunOver:运行结束
*************************************************************/
typedef enum
{
noRun,
RunStart,
Runing,
RunOver
}sRun_e;
/*************************************************************
/进程结构体
/process:进程
/pNum:进程序号
/cmdList:命令执行列表
*************************************************************/
typedef struct
{
QProcess *process;
uint8_t pNum;
QStringList cmdList;
}tProcess_t;
/*************************************************************
/进程参数结构体:进程列表参数不可更改,因此建立执行时参数结构体
/CmdRead:读命令执行信息
/CmdError:读命令执行错误信息
/isRun:运行状态
/rTime:运行计时
/pBarValue:运行进度条参数
*************************************************************/
typedef struct
{
QString CmdRead;
QString CmdError;
sRun_e isRun;
uint32_t rTime;
uint8_t pBarValue;
}pParam_t;
class Model_Process:public QObject
{
Q_OBJECT
public:
Model_Process();
~Model_Process();
//进程处理函数
void Process_Add();
void Process_Add(QString Workpath);
void Process_Del(uint8_t pNum);
//进程运行处理
void ProcessStart(uint8_t pNum,QString cmdStr);
void stopProcess(QString devNum,QString appStr);
void ProcessPathJump(QString path);
sRun_e GetProcessRunStatus(uint8_t pNum);
bool GetProcessIsRun();
private:
QList<tProcess_t > P_List;//进程列表
pParam_t pParam[P_Max]; //进程参数
int m_timerID1;//命令执行
//内部进程执行
void Process_Execute();
private slots:
void ProcessReadAll();
void ProcessReadError();
void ProcessshowState(QProcess::ProcessState state);
protected:
void timerEvent(QTimerEvent *event);
signals: //信号
void ProcessisOver(uint8_t pNum); //进程执行完毕
void ProcessBar(int Num,int value,QColor color); //进程进度条
void ProcessOutDeal(int pNum,QString String);
};
#endif // MODEL_PROCESS_H