一、知识储备
目前我查到的信息来看,没找到一个封装好的c++函数可以让我们方便得得到一个进程得运行时长,linux中普遍是通过ps命令来获取到进程的开始时间和运行时长。所以在c++中通过代码来启动命令行来得到结果并将获取到的时间变成总秒数
//将此命令中的pname和pid分别替换成自己的进程名和进程pid即可
//得到的就是一个"日-时:分:秒"结构的运行时长
ps -eo pid,etime,cmd | grep [pname] | grep [pid] | awk '{print $2}'
二、代码
逻辑:1.启动上述命令获取时长;2. 将的得到的时长各部分切分开存入vector; 3.将各部分都转成int比昂相加得到总的秒数
long ProcessKiller::get_process_runtime(int pid, const char *pname)
{
try{
char cmd[256] = {
0};
char buffer[256] = {
0};
if(pname) {
sprintf(cmd, "ps -eo pid,etime,cmd | grep %s | grep %d | awk '{print $2}'", pname, pid);
} else {
sprintf(cmd, "ps -eo pid,etime,cmd | grep %d | awk '{print $2}'", pid);
}
FILE *fpcmd = popen(cmd, "r");
//将命令获取的结果存入buffer
fgets(buffer, sizeof(buffer), fpcmd);
buffer[strlen(buffer)-1] = '\0';
string timestr=buffer;
std::cout<<"this is:"<<timestr<<std::endl;
std::vector<std::string> timetostring;
string sperator=":";
//buffer中存入的结果是"日-时:分:秒"的格式
//使用split函数将各部分切分存入vector
split(timestr, sperator, &timetostring);
int num=timetostring.size();
std::cout<<"size:"<<num<<std::endl;
//这个命令得到的时长至少是"分:秒"的格式,所以如果切分完少于两部分就有问题
if(num<2){
throw "get pid's runtime error!";
}
std::vector<std::string>::iterator it;
vector<int> times;
int tim;
// printf("tim: %d\n",tim);
//将各部分从string转成int
for(it=timetostring.begin();it!=timetostring.end();it++){
// std::cout<<"timetostring it:"<<*it<<std::endl;
sscanf((*it).c_str(), "%d", &tim);
times.push_back(tim);
// std::cout<<"int time:"<<tim<<std::endl;
}
long timeSec=0; //running time (second)
//day::hour::second::m
//将各部分时间相加得到总秒数
switch(num){
case 4: //日,时,分,秒
timeSec+= times[0]*86400+times[1]*3600+times[2]*60+times[3];
break;
case 3: //时,分,秒
timeSec+= times[0]*3600+times[1]*60+times[2];
break;
case 2: //分,秒
timeSec+= times[0]*60+times[1];
break;
default:
break;
}
printf("timeSec: %d\n",timeSec);
return timeSec;
}catch(std::string &e){
std::cout<<"err: "<<e<<std::endl;
throw e;
}catch(std::exception &e){
std::cout<<" exception err:"<<e.what()<<std::endl;
throw e.what();
}catch(...){
std::cout<<"get runtime unknown error!";
throw "get runtime unknown error!";
}
}
split函数
void ProcessKiller::split(std::string& s, std::string& delim,std::vector< std::string >* ret)
{
size_t last = 0;
size_t index;
if(s.find("-")==std::string::npos){
//std::cout<<"****there is - ";
index=s.find_first_of(delim,last);
}else{
index=s.find_first_of("-",last);
}
while (index!=std::string::npos)
{
ret->push_back(s.substr(last,index-last));
last=index+1;
index=s.find_first_of(delim,last);
}
if (index-last>0)
{
ret->push_back(s.substr(last,index-last));
}
}