项目要求获取多个进程的内存CPU资源利用情况,获取内存CPU资源利用的代码网上很多,但是要获取指定进程的PID却是没有找到。
他们正常例子都是获取当前进程的PID:
getpid();
Linux/Ubuntu下也没有直接的c的接口去调用。没办法,换个思路,用命令去实现。
获取指定进程名称的PID:
pidof 进程名
有了思路就好做了:
pid_t getProcessPidByName(const char *proc_name)
{
FILE *fp;
char buf[100];
char cmd[200] = {'\0'};
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);
}
}
printf("pid = %d \n", pid);
pclose(fp);
return pid;
}
获取到文件的PID后期很多东西就很方便,下面我们只要怎么获取对应的内存和cpu占用:
内存占用:
cat /proc/pid/status
得到内容如下:
Name: AIContaDriver.o
Umask: 0022
State: S (sleeping)
Tgid: 69945
Ngid: 0
Pid: 69945
PPid: 1
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 64
Groups:
NStgid: 69945
NSpid: 69945
NSpgid: 69935
NSsid: 69935
VmPeak: 426588 kB
VmSize: 426552 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 15144 kB
VmRSS: 6084 kB//内存 自己的机子自己去执行一下cat /proc/pid/status看看对应的是第几行-》VMRSS_LINE
RssAnon: 1060 kB
RssFile: 5024 kB
RssShmem: 0 kB
VmData: 75428 kB
VmStk: 132 kB
VmExe: 320 kB
VmLib: 12948 kB
VmPTE: 152 kB
VmSwap: 1812 kB
HugetlbPages: 0 kB
CoreDumping: 0
THP_enabled: 1
Threads: 10
SigQ: 0/15035
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000001006
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Cpus_allowed_list: 0-127
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1536706
nonvoluntary_ctxt_switches: 249
想要了解具体解析可以网上看下,这里我们需要知道内存的占用是
VmRSS: 6084 kB
命令:
cat /proc/stat
结果:
cpu 5448229 74 3245782 50924740 873190 0 505795 0 0 0
cpu0 441725 6 260114 6716261 132735 0 346332 0 0 0
cpu1 468292 10 269164 6685327 140659 0 72988 0 0 0
cpu2 932100 3 562943 5987590 79955 0 51371 0 0 0
cpu3 915177 16 551520 6012347 84624 0 17292 0 0 0
cpu4 454888 10 266837 6717587 122299 0 7982 0 0 0
cpu5 473489 10 271831 6676946 140623 0 4575 0 0 0
cpu6 878616 8 529561 6068946 86598 0 2829 0 0 0
cpu7 883940 8 533810 6059733 85695 0 2424 0 0 0
intr 446326587 34 4 0 2 2 0 0 0 1 0 4 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28521 0 0 0 0 0 0 0 0 2017726 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 548 0 3 1091102 37885 1529867 193101 0 37949 37949 37949 37949 1332465 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 703508425
btime 1667981583
processes 400320
procs_running 2
procs_blocked 0
softirq 205344652 5 82221747 19031 6202496 2055347 0 4326 74472273 210 40369217
第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了。下表解析第一行各数值的含义:
(jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间)
参数 | 解析(单位:jiffies) |
---|---|
user (5448229 ) | $ 从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。 |
nice (74) | $从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间 |
system (3245782) | $ 从系统启动开始累计到当前时刻,处于核心态的运行时间 |
idle (50924740) | $ 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间 |
iowait (873190) | $ 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41) |
irq (0) | $ 从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4) |
softirq (505795) | $ 从系统启动开始累计到当前时刻,软中断时间(since 2.6.0-test4) |
stealstolen(0) | $被盗时间 虚拟化环境中运行其他操作系统上花费的时间(since Linux 2.6.11) |
guest(0) | $ 来宾时间 操作系统运行虚拟CPU花费的时间(since Linux 2.6.24) |
guest_nice(0) | $ nice来宾时间 运行一个带nice值的guest花费的时间(since Linux 2.6.33) |
总的cpu时间:常用计算等式:CPU时间 = user + system + nice + idle + iowait + irq + softirq
命令:
cat /proc/pid/stat
结果:
69945 (Driver.out) S 1 69935 69935 0 -1 1077936128 1740 116737 19 9 3332 1294 83 11 20 0 10 0 5967937 436789248 1514 18446744073709551615 94165119266816 94165119594277 140726594687440 0 0 0 0 4102 0 0 0 0 17 0 0 0 29 0 0 94165119717872 94165119721488 94165145096192 140726594690725 140726594690775 140726594690775 140726594691014 0
解析
参数 | 解析 |
---|---|
pid(69945 ) | $ 进程ID。 |
(Driver.out) | $ 进程名称。 |
S | $ 进程状态, 任务的状态,R:runnign, S:sleeping (TASK_INTERRUPTIBLE), D:disk sleep (TASK_UNINTERRUPTIBLE), T: stopped, T:tracing stop,Z:zombie, X:dead。 |
euid、egid(1) | $ 有效的用户 id |
ppid(69935 ) | $ 父进程ID |
pgid(69935 ) | $ 线程组号 |
sessionid(0) | $ c该任务所在的会话组ID |
tty(-1) | $(pts/3) 该任务的tty终端的设备号,INT(34817/256)=主设备号,(34817-主设备号)=次设备号 |
tpgid(1077936128) | $ 终端的进程组号,当前运行在该任务所在终端的前台任务(包括shell 应用程序)的PID。 |
intflags(1740 ) | $ 进程标志位,查看该任务的特性 |
intminflt(116737) | $ 该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数 |
intcminflt(19 ) | $累计的该任务的所有的waited-for进程曾经发生的次缺页的次数目 |
intmajflt(9 ) | $该任务需要从硬盘拷数据而发生的缺页(主缺页)的次数 |
cmajflt(3332 ) | $累计的该任务的所有的waited-for进程曾经发生的主缺页的次数目 |
utime(1294 ) | $该任务在用户态运行的时间,单位为jiffies |
stime(83 ) | $该任务在核心态运行的时间,单位为jiffies |
cutime(11 ) | $累计的该任务的所有的waited-for进程曾经在用户态运行的时间,单位为jiffies |
cstime(20 ) | $累计的该任务的所有的waited-for进程曾经在核心态运行的时间,单位为jiffies |
priority(0) | $ 任务的动态优先级 |
进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。
a) 每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;
b) 每一个进程快照均为 (utime、stime、cutime、cstime)的4元组;
totalCpuTime1、totalCpuTime2、processCpuTime1、processCpuTime2
pcpu = 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数);
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#define VMRSS_LINE 22 //VmRSS: 所在行数
#define PROCESS_ITEM 14
typedef struct {
unsigned long user;
unsigned long nice;
unsigned long system;
unsigned long idle;
unsigned long iowait;
unsigned long irq;
unsigned long softirq;
unsigned long stealstolen;
unsigned long guest;
}Total_Cpu_Occupy_t;
typedef struct {
unsigned int pid;
unsigned long utime; //user time
unsigned long stime; //kernel time
unsigned long cutime; //all user time
unsigned long cstime; //all dead time
}Proc_Cpu_Occupy_t;
//获取第N项开始的指针
const char* get_items(const char*buffer ,unsigned int item){
const char *p =buffer;
int len = strlen(buffer);
int count = 0;
for (int i=0; i<len;i++){
if (' ' == *p){
count ++;
if(count == item -1){
p++;
break;
}
}
p++;
}
return p;
}
//获取总的CPU时间
unsigned long get_cpu_total_occupy(){
FILE *fd;
char buff[1024]={0};
Total_Cpu_Occupy_t t;
fd =fopen("/proc/stat","r");
if (nullptr == fd){
return 0;
}
fgets(buff,sizeof(buff),fd);
char name[64]={0};
sscanf(buff,"%s %ld %ld %ld %ld %ld %ld %ld %ld %ld",name,&t.user,&t.nice,&t.system,&t.idle,
&t.iowait,&t.irq,&t.softirq,&t.stealstolen,&t.guest);
fclose(fd);
return (t.user + t.nice + t.system + t.idle+t.iowait+ t.irq+ t.softirq+ t.stealstolen+t.guest);
}
//获取进程的CPU时间
unsigned long get_cpu_proc_occupy(unsigned int pid){
char file_name[64]={0};
Proc_Cpu_Occupy_t t;
FILE *fd;
char line_buff[1024]={0};
sprintf(file_name,"/proc/%d/stat",pid);
fd = fopen(file_name,"r");
if(nullptr == fd){
return 0;
}
fgets(line_buff,sizeof(line_buff),fd);
sscanf(line_buff,"%u",&t.pid);
const char *q =get_items(line_buff,PROCESS_ITEM);
sscanf(q,"%ld %ld %ld %ld",&t.utime,&t.stime,&t.cutime,&t.cstime);
fclose(fd);
return (t.utime + t.stime + t.cutime + t.cstime);
}
//获取CPU占用率
float get_proc_cpu(unsigned int pid){
unsigned long totalcputime1,totalcputime2;
unsigned long procputime1,procputime2;
totalcputime1=get_cpu_total_occupy();
procputime1=get_cpu_proc_occupy(pid);
usleep(200000);
totalcputime2=get_cpu_total_occupy();
procputime2=get_cpu_proc_occupy(pid);
float pcpu = 0.0;
if(0 != totalcputime2-totalcputime1){
pcpu=100.0 * (procputime2-procputime1)/(totalcputime2-totalcputime1);
}
return pcpu;
}
//获取进程占用内存
unsigned int get_proc_mem(unsigned int pid){
char file_name[64]={0};
FILE *fd;
char line_buff[512]={0};
sprintf(file_name,"/proc/%d/status",pid);
fd =fopen(file_name,"r");
if(nullptr == fd){
return 0;
}
char name[64];
int vmrss;
for (int i=0; i<VMRSS_LINE-1;i++){
fgets(line_buff,sizeof(line_buff),fd);
}
fgets(line_buff,sizeof(line_buff),fd);
sscanf(line_buff,"%s %d",name,&vmrss);
fclose(fd);
return vmrss;
}