Ubuntu/linux c开发(7)进程名称获取进程PID、CPU内存占用

1、获取进程pid

项目要求获取多个进程的内存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;
}

2、获取进程占用内存

获取到文件的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

3、获取进程占用CPU

3.1 获取总的cpu时间

命令:

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

3.2 进程占用CPU

命令:

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时间。

3.3 cpu占用计算

1. 采样两个足够短的时间间隔的cpu快照与进程快照,

a) 每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;

b) 每一个进程快照均为 (utime、stime、cutime、cstime)的4元组;

2. 分别根据结论2、结论3计算出两个时刻的总的cpu时间与进程的cpu时间,分别记作:

totalCpuTime1、totalCpuTime2、processCpuTime1、processCpuTime2

3. 计算该进程的cpu使用率

pcpu = 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数);

4、实现

#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;
}

你可能感兴趣的:(ubuntu,c++,linux,ubuntu,c语言)