from:https://www.cnblogs.com/cxjchen/archive/2013/03/30/2990548.html

Linux下没有直接可以调用系统函数知道CPU占用和内存占用。那么如何知道CPU和内存信息呢。只有通过proc伪文件系统来实现。

proc伪文件就不介绍了,只说其中4个文件。一个是/proc/stat,/proc/meminfo,/proc/<pid>/status,/proc/<pid>/stat

摘自:http://www.blogjava.net/fjzag/articles/317773.html

/proc/stat:存放系统的CPU时间信息

该文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。不同内核版本中该文件的格式可能不大一致,以下通过实例来说明数据该文件中各字段的含义。

实例数据:2.6.24-24版本上的

fjzag@fjzag-desktop:~$ cat /proc/stat

cpu 38082 627 27594 893908 12256 581 895 0 0

cpu0 22880 472 16855 430287 10617 576 661 0 0

cpu1 15202 154 10739 463620 1639 4 234 0 0

intr 120053 222 2686 0 1 1 0 5 0 3 0 0 0 47302 0 0 34194 29775 0 5019 845 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 1434984

btime 1252028243

processes 8113

procs_running 1

procs_blocked 0

第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了。下表解析第一行各数值的含义:

参数 解析(单位:jiffies)

(jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间)

user (38082) 从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。

nice (627) 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间

system (27594) 从系统启动开始累计到当前时刻,处于核心态的运行时间

idle (893908) 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间iowait (12256) 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)

irq (581) 从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4)

softirq (895) 从系统启动开始累计到当前时刻,软中断时间(since 2.6.0-test4)stealstolen(0) which is the time spent in other operating systems when running in a virtualized environment(since 2.6.11)

guest(0) which is the time spent running a virtual CPU for guest operating systems under the control of the Linux kernel(since 2.6.24)

结论2:总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen + guest

可以利用scanf,sscanf,fscanf读取这些信息,具体可以查man proc.我的程序中只取了前4个。

/proc/meminfo:存放系统的内存信息

[ubuntu@root ~]#cat /proc/meminfo 
MemTotal:        2061616 kB 
MemFree:         1093608 kB 
Buffers:          151140 kB 
Cached:           479372 kB 
SwapCached:            0 kB 
Active:           516964 kB 
Inactive:         374672 kB 
Active(anon):     261412 kB 
Inactive(anon):     5604 kB 
Active(file):     255552 kB 
Inactive(file):   369068 kB

……

别的就不说了,主要看第一个MemTotal,系统总的物理内存,它比真实的物理内存要小一点

/proc/<pid>/status:存放进程的CPU时间信息以及一些综合信息

[ubuntu@root ~]#cat /proc/889/status 
Name:    Xorg 
State:    S (sleeping) 
Tgid:    889 
Pid:    889 
PPid:    881 
TracerPid:    0 
Uid:    0    0    0    0 
Gid:    0    0    0    0 
FDSize:    256 
Groups:    
VmPeak:       99036 kB 
VmSize:       52424 kB 
VmLck:           0 kB 
VmHWM:       57004 kB 
VmRSS:       45508 kB 
VmData:       35668 kB 
VmStk:         136 kB 
VmExe:        1660 kB 
VmLib:        6848 kB 
VmPTE:         120 kB 
VmPeak是占用虚拟内存的峰值,也就是最高的一个值,而且是虚拟内存,所以有时候会比物理内存要大。PS和TOP指令都是利用VmPeak计算内存占用的。

VmRSS是进程所占用的实际物理内存。

/proc/<pid>/stat:保存着进程的CPU信息。

[ubuntu@root ~]#cat /proc/889/stat 
889 (Xorg) S 881 889 889 1031 889 4202752 5307477 0 0 0 34943 12605 0 0 20 0 1 0 8146 89399296 11377 4294967295 134512640 136211844 3221201472 3221200460 5456930 0 0 3149824 1367369423 3223423286 0 0 17 0 0 0 0 0 0

pid=889 进程号

utime=34943 该任务在用户态运行的时间,单位为jiffies

stime=12605 该任务在核心态运行的时间,单位为jiffies

cutime=0 所有已死线程在用户态运行的时间,单位为jiffies

cstime=0 所有已死在核心态运行的时间,单位为jiffies

可以利用scanf,sscanf,fscanf读取这些信息,具体可以查man proc.

结论3:进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。


以上这些数据都可以通过文件读取的方式,可以按照一行一行的读取,然后采用scanf,sscanf,fscanf获取信息。

占用内存的计算方法:

pmem = VmRSS / MemTotal * 100;

计算CPU占用的方法:

取一次processCpuTime1和totalCpuTime1;

间隔一段时间;

再取一次processCpuTime2和totalCpuTime2;

pcpu = 100 * (processCpuTime2 – processCpuTime1)/(totalCpuTime2 - totalCpuTime1);


代码

 1 get_cpu.h2 3 #ifdef __cplusplus4 extern "C"{5 #endif6 7 #define VMRSS_LINE 15//VMRSS所在行8 #define PROCESS_ITEM 14//进程CPU时间开始的项数9
10 typedef struct        //声明一个occupy的结构体
11 {
12         unsigned int user;  //从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。
13         unsigned int nice;  //从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
14         unsigned int system;//从系统启动开始累计到当前时刻,处于核心态的运行时间
15         unsigned int idle;  //从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间iowait (12256) 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)
16 }total_cpu_occupy_t;
17
18 typedef struct
19 {
20     pid_t pid;//pid号
21     unsigned int utime;  //该任务在用户态运行的时间,单位为jiffies
22     unsigned int stime;  //该任务在核心态运行的时间,单位为jiffies
23     unsigned int cutime;//所有已死线程在用户态运行的时间,单位为jiffies
24     unsigned int cstime;  //所有已死在核心态运行的时间,单位为jiffies
25 }process_cpu_occupy_t;
26
27     int get_phy_mem(const pid_t p);//获取占用物理内存
28     int get_total_mem();//获取系统总内存
29     unsigned int get_cpu_total_occupy();//获取总的CPU时间
30     unsigned int get_cpu_process_occupy(const pid_t p);//获取进程的CPU时间
31     const char* get_items(const char* buffer,int ie);//取得缓冲区指定项的起始地址
32
33     extern float get_pcpu(pid_t p);//获取进程CPU占用
34     extern float get_pmem(pid_t p);//获取进程内存占用
35     extern int get_rmem(pid_t p);//获取真实物理内存
36
37
38 #ifdef __cplusplus

  1 get_cpu.c2 3 #include <stdio.h>4 #include <stdlib.h>5 #include <unistd.h>   //头文件6 #include <assert.h>7 #include "get_cpu.h"8 9 int get_phy_mem(const pid_t p)10 {11     char file[64] = {0};//文件名12   13     FILE *fd;         //定义文件指针fd14     char line_buff[256] = {0};  //读取行的缓冲区15     sprintf(file,"/proc/%d/status",p);//文件中第11行包含着16 17     fprintf (stderr, "current pid:%d\n", p);                                                                                                  18     fd = fopen (file, "r"); //以R读的方式打开文件再赋给指针fd19 20     //获取vmrss:实际物理内存占用21     int i;22     char name[32];//存放项目名称23     int vmrss;//存放内存峰值大小24     for (i=0;i<VMRSS_LINE-1;i++)25     {26         fgets (line_buff, sizeof(line_buff), fd);27     }//读到第15行28     fgets (line_buff, sizeof(line_buff), fd);//读取VmRSS这一行的数据,VmRSS在第15行29     sscanf (line_buff, "%s %d", name,&vmrss);30     fprintf (stderr, "====%s:%d====\n", name,vmrss);31     fclose(fd);     //关闭文件fd32     return vmrss;33 }34 35 int get_rmem(pid_t p)36 {37     return get_phy_mem(p);38 }39 40 41 int get_total_mem()42 {43     char* file = "/proc/meminfo";//文件名44   45     FILE *fd;         //定义文件指针fd46     char line_buff[256] = {0};  //读取行的缓冲区                                                                                                47     fd = fopen (file, "r"); //以R读的方式打开文件再赋给指针fd48 49     //获取memtotal:总内存占用大小50     int i;51     char name[32];//存放项目名称52     int memtotal;//存放内存峰值大小53     fgets (line_buff, sizeof(line_buff), fd);//读取memtotal这一行的数据,memtotal在第1行54     sscanf (line_buff, "%s %d", name,&memtotal);55     fprintf (stderr, "====%s:%d====\n", name,memtotal);56     fclose(fd);     //关闭文件fd57     return memtotal;58 }59 60 float get_pmem(pid_t p)61 {62     int phy = get_phy_mem(p);63       int total = get_total_mem();64       float occupy = (phy*1.0)/(total*1.0);65       fprintf(stderr,"====process mem occupy:%.6f\n====",occupy);66       return occupy;67 }68 69 unsigned int get_cpu_process_occupy(const pid_t p)70 {71     char file[64] = {0};//文件名72     process_cpu_occupy_t t;73   74     FILE *fd;         //定义文件指针fd75     char line_buff[1024] = {0};  //读取行的缓冲区76     sprintf(file,"/proc/%d/stat",p);//文件中第11行包含着77 78     fprintf (stderr, "current pid:%d\n", p);                                                                                                  79     fd = fopen (file, "r"); //以R读的方式打开文件再赋给指针fd80     fgets (line_buff, sizeof(line_buff), fd); //从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里81 82     sscanf(line_buff,"%u",&t.pid);//取得第一项83     char* q = get_items(line_buff,PROCESS_ITEM);//取得从第14项开始的起始指针84     sscanf(q,"%u %u %u %u",&t.utime,&t.stime,&t.cutime,&t.cstime);//格式化第14,15,16,17项85 86     fprintf (stderr, "====pid%u:%u %u %u %u====\n", t.pid, t.utime,t.stime,t.cutime,t.cstime);87     fclose(fd);     //关闭文件fd88     return (t.utime + t.stime + t.cutime + t.cstime);89 }90 91 92 unsigned int get_cpu_total_occupy()93 {94     FILE *fd;         //定义文件指针fd95     char buff[1024] = {0};  //定义局部变量buff数组为char类型大小为102496     total_cpu_occupy_t t;97                                                                                                              98     fd = fopen ("/proc/stat", "r"); //以R读的方式打开stat文件再赋给指针fd99     fgets (buff, sizeof(buff), fd); //从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里
100     /*下面是将buff的字符串根据参数format后转换为数据的结果存入相应的结构体参数 */
101     char name[16];//暂时用来存放字符串
102     sscanf (buff, "%s %u %u %u %u", name, &t.user, &t.nice,&t.system, &t.idle);
103
104
105     fprintf (stderr, "====%s:%u %u %u %u====\n", name, t.user, t.nice,t.system, t.idle);
106     fclose(fd);     //关闭文件fd
107     return (t.user + t.nice + t.system + t.idle);
108 }
109
110
111 float get_pcpu(pid_t p)
112 {
113     unsigned int totalcputime1,totalcputime2;
114       unsigned int procputime1,procputime2;
115     totalcputime1 = get_cpu_total_occupy();
116     procputime1 = get_cpu_process_occupy(p);
117     usleep(500000);//延迟500毫秒
118     totalcputime2 = get_cpu_total_occupy();
119     procputime2 = get_cpu_process_occupy(p);
120     float pcpu = 100.0*(procputime2 - procputime1)/(totalcputime2 - totalcputime1);
121     fprintf(stderr,"====pcpu:%.6f\n====",pcpu);
122     return pcpu;
123 }
124
125 const char* get_items(const char* buffer,int ie)
126 {
127     assert(buffer);
128     char* p = buffer;//指向缓冲区
129     int len = strlen(buffer);
130     int count = 0;//统计空格数
131     if (1 == ie || ie < 1)
132     {
133         return p;
134     }
135     int i;
136
137     for (i=0; i<len; i++)
138     {
139         if (' ' == *p)
140         {
141             count++;
142             if (count == ie-1)
143             {
144                 p++;
145                 break;
146             }
147         }
148         p++;
149     }
150
151     return p;
152 }

转载于:https://www.cnblogs.com/the-tops/p/8274442.html

Linux下计算进程的CPU占用和内存占用的编程方法[转]相关推荐

  1. linux查询内存条个数,linux下查看内存条数及每根内存大小的实现方法(推荐)

    在linux系统中,查看内存条个数,及每根内存的大小,可以使用dmidecode命令. 如下: #dmidecode | grep -A16 "Memory Device$" 输出 ...

  2. 利用Linux的/proc/stat获取指定进程的cpu占有率及内存

    利用Linux的 /proc/stat计算进程的cpu占有率和内存 计算的是进程多个cpu的平均占有率,并不是每个cpu的,所以和top命令中的不一样 getinfo.cpp 1 #include&l ...

  3. linux下查看进程占用端口和端口占用进程命令

    Linux下查看进程占用端口: 查看程序对应进程号:ps –ef|grep 进程名 REDHAT :查看进程号所占用的端口号:netstat –nltp|grep 进程号 ubuntu:查看进程占用端 ...

  4. linux监测指定进程的CPU及物理内存消耗情况(c程序)

    近日,由于工作要求,研究了一下如何在linux系统下对某个指定的单个进程进行监测,分析其CPU及物理内存的使用情况,并基于c语言写了一个独立的模块,完整的实现上述功能.现将整个模块的代码贴上,以便日后 ...

  5. linux下查看进程的线程数,linux查看进程的线程数

    top -H -p $PID  #查看对应进程的那个线程占用CPU过高 1.top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程.否则,它一行 ...

  6. Linux VPS服务器根据CPU负载及内存占用自动重启的bash shell脚本

    Linux VPS服务器根据CPU负载及内存占用自动重启的bash shell脚本 288月2011 0 主要用于监控 linux 服务器负载及内存占用,如 MySQl.php-fpm,当负载或内存占 ...

  7. Linux下如何查看高CPU占用率线程

    转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...

  8. Linux下查看进程和线程

    在linux中查看线程数的三种方法 1.top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程.否则,它一行显示一个进程. 2.ps xH 手册 ...

  9. java 收集系统资源_方法:Linux 下用JAVA获取CPU、内存、磁盘的系统资源信息

    CPU使用率: InputStream is = null; InputStreamReader isr = null; BufferedReader brStat = null; StringTok ...

  10. linux进程和线程教程,Linux下查看进程和线程

    在Linux中查看线程数的三种方法 1.top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程.否则,它一行显示一个进程. 2.ps xH 手册 ...

最新文章

  1. 学python人工智能需要多久_人工智能Python开发怎么学才能最快入门
  2. scrapy (2)下载图片及存储信息
  3. hdu5489(2015合肥网络赛F题)
  4. cf446C DZY Loves Fibonacci Numbers
  5. 【RTD】AD7793三线式铂电阻PT100/PT1000应用
  6. 世界地图可以无限放大_国外测评 | 老蛙百微镜头的全方位解析,2倍放大倍率的优质表现!...
  7. Illustrator CC从入门到精通 精装版-李发展-专题视频课程
  8. html邮件和英文邮件,英文邮件中Best wishes和Best regards的区别
  9. java虚拟键盘_如何用Java为其他程序制作虚拟键盘?
  10. map集合用于存储信息(映射关系)
  11. HTC Vive开发笔记之手柄震动
  12. 计算机蓝屏显示的英文是什么,电脑蓝屏出现一堆英文怎么解决?
  13. 单独聊一聊CTWing软硬交互
  14. 如何使用Angular Router在Angular 9应用程序中创建导航
  15. Python实战-新能源王者宁德时代股权穿透研究(附完整代码)
  16. 本地搭建Agriculture_KnowledgeGraph农业知识图谱环境时遇到的问题及解决办法
  17. torch.nn.Linear详解
  18. jquery控制元素的隐藏和显示的几种方法。
  19. 想做视频剪辑师到底累不累?
  20. Custom Data Objects

热门文章

  1. struts一个action处理多个方法
  2. 【智能家居篇】wifi网络结构(下)
  3. chkconfig用法
  4. T-SQL Parser
  5. csv数据源的创建(一)
  6. .net中模拟键盘和鼠标操作
  7. C#DataGridView中的常用技巧
  8. [树上倍增][最小生成树]JZOJ P4313——电话线铺设
  9. mac 下php运行bug
  10. Android 使用 TableLayout 布局拉伸宽度