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

1、获取进程pid
项目要求获取多个进程的内存CPU资源利用情况,获取内存CPU资源利用的代码网上很多,但是要获取指定进程的PID却是没有找到。
他们正常例子都是获取当前进程的PID:

getpid();
1
Linux/Ubuntu下也没有直接的c的接口去调用。没办法,换个思路,用命令去实现。

获取指定进程名称的PID:

pidof  进程名
1
有了思路就好做了:


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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2、获取进程占用内存
获取到文件的PID后期很多东西就很方便,下面我们只要怎么获取对应的内存和cpu占用:
内存占用:

cat /proc/pid/status
1
得到内容如下:

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
想要了解具体解析可以网上看下,这里我们需要知道内存的占用是

VmRSS:      6084 kB
1
3、获取进程占用CPU
3.1 获取总的cpu时间
命令:

cat /proc/stat
1
结果:

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第一行的数值表示的是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
1
3.2 进程占用CPU
命令:

cat /proc/pid/stat
1
结果:

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
1
解析

参数    解析
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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值