计算Linux系统和进程和线程的CPU及内存使用率(c++源码)

proc文件系统下的

/proc/stat,

/proc/meminfo,

/proc/<pid>/status,

/proc/<pid>/stat

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

进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime

占用内存的计算方法:pmem = VmRSS / MemTotal * 100

计算CPU占用的方法:

取一次processCpuTime1和totalCpuTime1;

间隔一段时间;

再取一次processCpuTime2和totalCpuTime2;

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

//-----------------mytop.cpp------------------------

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include <string>

#include<unistd.h>

#include<fcntl.h>

#include<ctype.h>

#include <sys/types.h>

#include <dirent.h>

#include <errno.h>

#include <asm/page.h>

#include <vector>

#include <assert.h>

#include<iostream>

using namespace std;

#define CK_TIME 1

struct FileAttribute

{

string path;

string name;

unsigned long long size;

time_t  modify_timestamp;

bool    is_dir;

};

int EnumFile(vector<FileAttribute> &file_array, string _dir)

{

DIR* dir=opendir(_dir.c_str());  //(".")

if(dir == NULL)

return 0;

struct dirent* entry;

while((entry=readdir(dir)))

{

if( strcmp( entry->d_name,".") ==0 || strcmp( entry->d_name,"..") ==0 )

continue;

FileAttribute fi;

fi.name = entry->d_name;

fi.is_dir = false;

string path;

if(_dir=="/"||(_dir.rfind("/")+1)>=_dir.length())

path=_dir+fi.name;

else

path = _dir+"/"+fi.name;

struct stat statbuf;

if (stat( path.c_str(),&statbuf ) < 0)

{

closedir(dir);

printf("stat error ! message: %s\n",strerror(errno));

return 0;

}

if (S_ISDIR(statbuf.st_mode))

{

fi.is_dir = true;

}

fi.size = statbuf.st_size;

fi.modify_timestamp =statbuf.st_mtime;

fi.path = path;

file_array.push_back(fi);

}

closedir(dir);

return file_array.size();

}

char * skip_token(const char *p)

{

while (isspace(*p)) p++;

while (*p && !isspace(*p)) p++;

return (char *)p;

}

int get_sys_mem(char *mem)

{

int tm,fm,bm,cm,ts,fs;

char buffer[4096+1];

char sys_mem[1024];

int fd, len;

char *p;

//fd = open("/proc/meminfo", O_RDONLY);

if((fd = open("/proc/meminfo", O_RDONLY)) < 0)

{

perror("open /proc/meminfo file failed");

exit(1);

}

len = read(fd, buffer, sizeof(buffer)-1);

close(fd);

buffer[len] = ‘\0‘;

p = buffer;

p = skip_token(p);

tm = strtoul(p, &p, 10); /* total memory */

p = strchr(p, ‘\n‘);

p = skip_token(p);

fm= strtoul(p, &p, 10); /* free memory */

p = strchr(p, ‘\n‘);

p = skip_token(p);

bm= strtoul(p, &p, 10); /* buffer memory */

p = strchr(p, ‘\n‘);

p = skip_token(p);

cm= strtoul(p, &p, 10); /* cached memory */

for(int i = 0; i< 8 ;i++)

{

p++;

p = strchr(p, ‘\n‘);

}

p = skip_token(p);

ts= strtoul(p, &p, 10); /* total swap */

p = strchr(p, ‘\n‘);

p = skip_token(p);

fs= strtoul(p, &p, 10); /* free swap */

sprintf(mem,"Mem: %luk total,%luk used,%luk free,%luk buffer\nSwap: %luk total,%luk used, %luk  free,%luk cached\n",

tm,tm-fm,fm,bm,ts,ts-fs,fs,cm);

//printf("%s\n",mem);

return tm;

}

int get_phy_mem(pid_t pid,char* ph)

{

char file[64] = {0};//文件名

FILE *fd;         //定义文件指针fd

char line_buff[256] = {0};  //读取行的缓冲区

sprintf(file,"/proc/%d/status",pid);

//fd = fopen (file, "r");

if((fd = fopen (file, "r"))==NULL)

{

printf("Can‘t open file\n");

exit(1);

}

//获取vmrss:实际物理内存占用

int i;

char name1[32];//存放项目名称

int vmrss;//存放内存峰值大小

char name2[32];

int vmsize;

for (i=0;i<12;i++)

{

fgets (line_buff, sizeof(line_buff), fd);

}

fgets (line_buff, sizeof(line_buff), fd);

sscanf (line_buff, "%s %d", name2,&vmsize);

//fprintf (stderr, "====%s:%d====\n", name2,vmsize);

for (i=0;i<2;i++)

{

fgets (line_buff, sizeof(line_buff), fd);

}

fgets (line_buff, sizeof(line_buff), fd);//读取VmRSS这一行的数据,VmRSS在第15行

sscanf (line_buff, "%s %d", name1,&vmrss);

//fprintf (stderr, "====%s:%d====\n", name1,vmrss);

fclose(fd);     //关闭文件fd

sprintf(ph,"VIRT=%dKB RES=%dKB",vmsize,vmrss);

//printf("=+=+=%s\n",ph);

return vmrss;

}

int get_process_time(pid_t pid,int tid)

{

char szStatStr[1024];

char pname[64];

char state;

int ppid,pgrp,session,tty,tpgid;

unsigned int    flags,minflt,cminflt,majflt,cmajflt;

int utime,stime,cutime,cstime,counter,priority;

unsigned int  timeout,itrealvalue;

int           starttime;

unsigned int  vsize,rss,rlim,startcode,endcode,startstack,kstkesp,kstkeip;

int signal,blocked,sigignore,sigcatch;

unsigned int  wchan;

char file_stat [1024];

if(tid==0)

{

sprintf( file_stat,"/proc/%d/stat",pid );

}else if(tid!=-1)

{

sprintf( file_stat,"/proc/%d/task/%d/stat",pid,tid );

}

//printf("open file %s\n",file_stat);

FILE* fid;

//fid = fopen(file_stat,"r");

if((fid = fopen (file_stat, "r"))==NULL)

{

printf("Can‘t open file\n");

exit(1);

}

fgets(szStatStr,sizeof(szStatStr),fid);

fclose(fid);

//printf("+++szStatStr=%s\n",szStatStr);

sscanf (szStatStr, "%u", &pid);

char  *sp, *t;

sp = strchr (szStatStr, ‘(‘) + 1;

t = strchr (szStatStr, ‘)‘);

strncpy (pname, sp, t - sp);

sscanf (t + 2, "%c %d %d %d %d %d %u %u %u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d %d %d %d %u",

/*     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*/

&state,&ppid,&pgrp,&session,&tty,&tpgid,&flags,&minflt,&cminflt,&majflt,&cmajflt,&utime,&stime,&cutime,&cstime,&counter,

&priority,&timeout,&itrealvalue,&starttime,&vsize,&rss,&rlim,&startcode,&endcode,&startstack,

&kstkesp,&kstkeip,&signal,&blocked,&sigignore,&sigcatch,&wchan);

/*printf("-------%c %d %d %d %d %d %u %u %u %u %u -%d -%d -%d -%d %d %d %u %u %d %u %u %u %u %u %u %u %u %d %d %d %d %u",

state,ppid,pgrp,session,tty,tpgid,flags,minflt,cminflt,majflt,cmajflt,utime,stime,cutime,cstime,counter,

priority,timeout,itrealvalue,starttime,vsize,rss,rlim,startcode,endcode,startstack,

kstkesp,kstkeip,signal,blocked,sigignore,sigcatch,wchan);

*/

//printf("+++%lu %lu %lu %lu\n",utime,stime,cutime,cstime);

int p_cpu=utime+stime+cutime+cstime;

return p_cpu;

}

string GetCpuMem( size_t pid, string &cpu ,string &mem,int tid=0 )

{

FILE *fp;

char buf[128];

char tcpu[7];

char result[512];

char ccpu[256];

char cmem[256];

char process[1028];

unsigned int  user,nice,sys,idle,iowait,irq,softirq,steal;

unsigned int  all1,all2;

unsigned int   us1,ni1,sy1,id1,io1,ir1,so1,st1;

unsigned int   us2,ni2,sy2,id2,io2,ir2,so2,st2;

unsigned int  p_cpu1,p_cpu2;

float usage,niage,syage,idage,ioage,irage,soage,stage;

//fp = fopen("/proc/stat","r");

if((fp = fopen ("/proc/stat", "r"))==NULL)

{

printf("Can‘t open file\n");

exit(1);

}

fgets(buf,sizeof(buf),fp);

sscanf(buf,"%s%d%d%d%d%d%d%d%d",tcpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq,&steal);

//printf("%s,%d,%d,%d,%d,%d,%d,%d,%d\n",tcpu,user,nice,sys,idle,iowait,irq,softirq,steal);

all1 = user+nice+sys+idle+iowait+irq+softirq+steal;

us1=user;ni1=nice;sy1=sys;id1=idle;

io1=iowait;ir1=irq;so1=softirq;st1=steal;

//=============================================

char file_dir[256];

sprintf(file_dir,"/proc/%d/task",pid);

string _dir=file_dir;

//printf("-----%s\n",file_dir);

vector<FileAttribute> file_array;

int file_sum=EnumFile(file_array,_dir);

unsigned int a[file_sum];

unsigned int b[file_sum];

unsigned int b2[file_sum];

int i=0;

if(tid==-1)

{

for(vector<FileAttribute>::iterator it=file_array.begin();it!=file_array.end();it++)

{

_dir=(*it).name;

//cout<<"_dir="<<_dir<<endl;

a[i]=atoi( _dir.c_str());

i++;

}

for(int j=0;j<file_sum;j++)

{

b[j]=get_process_time( pid,a[j]);

}

}else

{

p_cpu1= get_process_time( pid, tid);

}

//===========================================

/*第二次取数据*/

sleep(CK_TIME);

rewind(fp);

memset(buf,0,sizeof(buf));

tcpu[0] = ‘\0‘;

user=nice=sys=idle=iowait=irq=softirq=steal=0;

fgets(buf,sizeof(buf),fp);

sscanf(buf,"%s%d%d%d%d%d%d%d%d",tcpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq,&steal);

//printf("%s,%d,%d,%d,%d,%d,%d,%d,%d\n",tcpu,user,nice,sys,idle,iowait,irq,softirq,steal);

us2=user;ni2=nice;sy2=sys;id2=idle;

io2=iowait;ir2=irq;so2=softirq;st2=steal;

all2 = user+nice+sys+idle+iowait+irq+softirq+steal;

usage =(float)((us2-us1)+(ni2-ni1))/(all2-all1)*100 ;

syage=(float)((sy2-sy1)+(ir2-ir1)+(so2-so1))/(all2-all1)*100 ;

idage=(float)(id2-id1)/(all2-all1)*100;

niage=(float)(ni2-ni1)/(all2-all1)*100;

ioage=(float)(io2-io1)/(all2-all1)*100;

irage=(float)(ir2-ir1)/(all2-all1)*100;

soage=(float)(so2-so1)/(all2-all1)*100;

stage=(float)(so2-so1)/(all2-all1)*100;

if(tid==-1)

{

for(int j=0;j<file_sum;j++)

{

b2[j]=get_process_time( pid,a[j]);

}

}else

{

p_cpu2= get_process_time( pid, tid);

}

int NUM_PROCS = sysconf(_SC_NPROCESSORS_CONF);

//printf("======%d",NUM_PROCS);

float prcpu[file_sum];

float pcpu;

if(tid==-1)

{

for(int j=0;j<file_sum;j++)

{

prcpu[j]=(float)(b2[j]-b[j])/(all2-all1)*NUM_PROCS*100;

}

}else

{

pcpu = (float)(p_cpu2 - p_cpu1)/(all2-all1)*NUM_PROCS*100;

}

//printf("cpu(s): %.2f\% ,%.2f\% ,%.2f\% ,%.2f\% ,%.2f\% ,%.2f\% ,%.2f\% ,%.2f\% \n",

//          usage,syage,niage,idage,ioage,irage,soage,stage);

sprintf(ccpu,"Cpu(s):  %.2f%%us,%.2f%%sy,%.2f%%ni,%.2f%%id,%.2f%%wa,%.2f%%hi,%.2f%%si,%.2f%%st\n",

usage,syage,niage,idage,ioage,irage,soage,stage);

fclose(fp);

char ph[256];

long page_size = sysconf(_SC_PAGESIZE)>>10;

float pmem=(get_phy_mem(pid,ph)*page_size)/get_sys_mem(cmem)*100;

cpu=ccpu;

mem=cmem;

if(tid==-1)

{

int offset = 0;

for(int j=0;j<file_sum;j++)

{

//printf("PID=%d  TID=%d  %.2f%%CPU  %.2f%%MEM %s\n",pid,a[j],prcpu[j],pmem,ph);

offset += sprintf(process+ offset,"PID=%d  TID=%d  %.2f%%CPU  %.2f%%MEM %s\n",pid,a[j],prcpu[j],pmem,ph);

}

//printf("%s\n",process);

}else

{

sprintf(process,"PID=%d  TID=%d  %.2f%%CPU  %.2f%%MEM %s",pid,tid,pcpu,pmem,ph);

//printf("PID=%d  TID=%d  %.2f%%CPU  %.2f%%MEM %s\n",pid,tid,pcpu,pmem,ph);

}

//==================================================

sprintf(result,"%s%s%s",ccpu,cmem,process);

string s=result;

return s;

}

int main(int argc, char** argv)

{

int pid=0;

int tid=0;

string cpu,mem;

if( argc > 1 )

pid = atoi(argv[1]);

else{

pid = getpid();

}

if( argc > 2 )

tid = atoi(argv[2]);

//printf("pid=%d,tid=%d\n",pid,tid);

while(1)

{

cout<<"----------------------------"<<endl;

string s=GetCpuMem(pid,cpu,mem,tid);

cout<<s<<endl;

}

return 0;

}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

编译:g++ -g -o mytop mytop.cpp

运行:./mytop      (默认程序mytop进程的pid,tid默认为0)

./mytop   pid  (指定程序的pid,tid默认为0)

./mytop pid   tid  (指定程序的进程pid与及程序线程的tid)

./mytop pid -1    (指定程序的全部线程)

时间: 2024-10-06 17:19:40

计算Linux系统和进程和线程的CPU及内存使用率(c++源码)的相关文章

linux测试某进程占用oi、cpu、内存的使用情况

pidstat 概述 pidstat是sysstat工具的一个命令,用于监控全部或指定进程的cpu.内存.线程.设备IO等系统资源的占用情况.pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统计信息. pidstat 安装 pidstat 是sysstat软件套件的一部分,sysstat包含很多监控linux系统状态的工具,它能够从大多数linux发行版的软件源中获得. 在Debia

Linux系统编程——进程和线程的区别与联系

在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体. 为了让进程完成一定的工作,进程必须至少包含一个线程. 进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统.操作系统会以进程为单位,分配系统资源,所以我们也说,进程是资源分配的最小单位.更多详情,请看<进程的介绍>. 线程存在与进程当中,是操作系统调度执行的最小单位.

linux学习之进程,线程和程序

                                                                                  程序.进程和线程的概念 1:程序和进程的差别 进程的出现最初是在UNIX下,用于表示多用户,多任务的操作系统环境下,应用程序在内存环境中基本执行单元的概念.进程是UNIX操作系统环境最基本的概念.是系统资源分配的最小单位.UNIX操作系统下的用户管理和资源分配等工作几乎都是操作系统通过对应用程序进程的控制实现的! 当使用c c++ j

Linux系统中进程的创建

1.Linux中的进程 进程是程序执行的一个实例,也是系统资源调度的最小单位.如果同一个程序被多个用户同时运行,那么这个程序就有多个相对独立的进程,与此同时他们又共享相同的执行代码,在Linux系统中进程的概念类似于任务或者线程(task & threads). 进程是一个程序运行时候的一个实例实际上说的是它就是一个可以充分描述程序以达到了其可以运行状态的的一个数据和代码集合.一个进程会被产生并会复制出自己的子代,类似细胞分裂一样.从系统的角度来看进程的任务实际上就是担当承载系统资源的单位,系统

Linux下的进程与线程(二)—— 信号

Linux进程之间的通信: 本文主要讨论信号问题. 在Linux下的进程与线程(一)中提到,调度器可以用中断的方式调度进程. 然而,进程是怎么知道自己需要被调度了呢?是内核通过向进程发送信号,进程才得以知道的. Linux系统的进程之间是通过信号来通信的. 程序员在Shell上显式地发送信号使用的是kill命令,原型如下: kill -sigid [-]pid 其中, sigid指示的是信号的id,pid前若有-,则pid代表的为进程组id,否则pid代表的为进程id kill函数也有相同的作用

Linux系统编程@进程通信(一)

进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统的一个分支) POSIX进程间通信(POSIX:可移植操作系统接口,为了提高UNIX环境下应用程序的可移植性.很多其他系统也支持POSIX标准(如:DEC OpenVMS和Windows).) 现在Linux使用的进程间通信方式包括: 管道(pipe).有名管道(FIFO) 信号(signal) 消

asp.net core2.0 部署centos7/linux系统 --守护进程supervisor(二)

原文:asp.net core2.0 部署centos7/linux系统 --守护进程supervisor(二) 续上一篇文章:asp.net core2.0 部署centos7/linux系统 --安装部署(一),遗留的问题而来,对程序添加守护进程,使网站可以持续化的运行起来. ? 1.介绍supervisor ?? ?Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,

查看本机CPU、内存使用率前10的进程

在日常运维工作中,经常会查看占用当前系统CPU或内存使用率前几位的进程情况.下面列出这些查看的命令: 查看占用CPU最高的5个进程ps aux | sort -k3rn | head -5或者top (然后按下P,注意大写,CPU使用率降序) 查看占用内存最高的5个进程ps aux | sort -k4rn | head -5或者top (然后按下M,注意大写,内存使用率降序) 查看所有信息使用命令ps aux sort -rn 降序sort -k3rn 按照第三列降序 sort|uniq 排序

Java开源生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案(源码可下载)

Java开源生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案(源码可下载) 说明:Java开源生鲜电商中OMS订单系统中并发问题和锁机制的探讨与解决方案: 问题由来     假设在一个订单系统中(以火车票订单系统为例),用户A,用户B都要预定从成都到北京的火车票,A.B在不同的售票窗口均同时查询到了某车厢卧铺中.下铺位有空位.用户A正在犹豫订中铺还是下铺,这时用户B果断订购了下铺.当用户A决定订下铺时,系统提示下铺已经被预订,请重新选择铺位.在这个系统场景中,我们来探讨一下,火车票