一、windows环境下
1、进程查询函数
processCount函数用于查询系统所有运行的进程中该进程运行的数目,例如启动了5个A进程,该函数查询返回的结果就为5。
windows下使用了API插口查询进程信息,该函数纯C++无Qt库相关代码,注释对代码进行了详尽解释。
int processCount(const char* processName)
{
int countProcess = 0;
//CreateToolhelp32Snapshot 获取系统中正在运行的进程信息,线程信息等
HANDLE toolHelp32Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (((int)toolHelp32Snapshot) != -1)
{
PROCESSENTRY32 processEntry32;
processEntry32.dwSize = sizeof(processEntry32);
if(Process32First(toolHelp32Snapshot, &processEntry32)) //判断进程获取首进程是否存在
{
do
{
int iLen = 2 * wcslen(processEntry32.szExeFile); //wcslen - 计算宽字符串的长度
char* currentProcessName = new char[iLen + 1];
wcstombs(currentProcessName, processEntry32.szExeFile, iLen + 1); //将宽字符转换成多字符
if (strcmp(processName, currentProcessName) == 0) //对比进程名
countProcess++;
delete []currentProcessName;
}while (Process32Next(toolHelp32Snapshot, &processEntry32)); //进程获取函数,获取下一个进程名
}
//关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。
CloseHandle(toolHelp32Snapshot);
}
return countProcess;
}
2、进程守护代码
进程守护似乎就是使用一个进程去定时查询另外一个被守护的进程是否存在,不存在则须要启动该进程。代码如下,运行时,首先须要获取被守护的进程APP,使用读取配置文件的方法,假如配置文件不存在(首次启动该代码),则须要选择被守护的进程,之后将选择的APP路劲存入配置文件linux操作系统教程,供上次启动读取使用。
int main(int argc, char *argv[])
{
QSettings sets("sys.ini", QSettings::IniFormat);
QString targetExePath = sets.value(KEY_EXE_PATH).toString();
if ("" == targetExePath)
{
//首次需要选择 被守护的进程
QString exepath = QFileDialog::getOpenFileName(nullptr, "选择程序", "D:/", "Exe files (*.exe)");
if ("" != exepath)
sets.setValue(KEY_EXE_PATH, exepath); //写入配置文件
}
while (1) //死循环,不断查询判断
{
//targetExePath = sets.value(KEY_EXE_PATH).toString();
QString exeName = targetExePath.split('/').last();
QDateTime strtTime = QDateTime::currentDateTime();
int countProcess = processCount(exeName.toStdString().c_str()); // 查询该进程运行数量
qDebug()<<"use times for Query process:"<<strttime.msecsto(qdatetime::currentdatetime())<<"(ms) countProcess:"</strttime.msecsto(qdatetime::currentdatetime())<<<<countprocess;</countprocess;
if (countProcess == 0)
system(targetExePath.toStdString().c_str()); //关闭状态 重启进程,注意:这里实际运行会阻塞在这里,一直等到被守护的线程结束。
Sleep(3000);
}
}
二、linux环境下
1、进程查询函数
原理:使用popen函数+pidof命令查询对应进程的pidlinux环境进程间通信,该方式的缺点就是不能像windows那样读取所有进程名因而获取该进程运行的数目。所以,假若一个程序加载多个进程(同程序进程名相同,pid不同),使用该方式只能获取最后一个启动的进程pid。
popen属于标准I/O函数库中函数,使用该函数启动另外一个进程去执行一个shell命令行。
这儿我们称调用popen的进程为父进程,由popen启动的进程称为子进程。
popen函数还创建一个管线用于母子进程间通讯。父进程要么从管线读信息LINUX虚机,要么向管线写信息,至于是读还是写取决于父进程调用popen时传递的参数。
实现函数如下,函数参数输入进程名linux环境进程间通信,返回进程的pid,倘若返回-1则表示进程不存在或未运行。
pid_t getProcessPidByName(const char *proc_name)
{
FILE *fp;
char buf[100];
char cmd[200] = {''};
pid_t pid = -1;
sprintf(cmd, "pidof %s", proc_name);
if((fp = popen(cmd, "r")) != NULL)
{
if(fgets(buf, 255, fp) != NULL)
pid = atoi(buf);
}
pclose(fp);
return pid;
}
2、进程守护代码
实现上windows代码已然比较详尽了,所以这儿linux下简单实现。代码如下:
int main(int argc, char *argv[])
{
while(1)
{
if(getProcessPidByName("qtcreator") == -1)
{
printf("open APP qtcreator...");
system("qtcreator &"); //启动软件
}
sleep(5); //需要大于软件启动时间
}
return 0;
}