linux 监控进程

  1 #include<stdlib.h>                                                                          
  2 #include<string.h>
  3 #include<stdio.h>
  4 #include<unistd.h>
  5 #include<sys/time.h>
  6 #include <sys/wait.h>
  7 #include <sys/types.h>
  8 
  9 #define SHELL "/bin/bash"
 10 #define VMRSS_LINE 17
 11 #define VMSIZE_LINE 13
 12 #define PROCESS_TIME 14
 13 
 14 typedef struct{
 15     unsigned long user; //用户态的CPU时间
 16     unsigned long nice; //nice值为负的进程所占用的CPU时间
 17     unsigned long system;//核心时间
 18     unsigned long idle; //硬盘IO等待时间以外其它等待时间
 19 }Total_Cpu_Occupy_t;
 20 
 21 typedef struct{
 22     unsigned int pid;
 23     unsigned long utime;
 24     unsigned long stime;
 25     unsigned long cutime;
 26     unsigned long cstime;
 27 }Proc_Cpu_Occupy_t;
 28 
 29 const char* get_items(const char*buffer,unsigned int item)
 30 {
 31     const char*p=buffer;
 32     int len = strlen(buffer);
 33     int count=0;
 34     for (int i=0;i<len;i++){
 35         if(' '==*p){
 36             count++;
 37             if(count==item-1){
 38                 p++;
 39                 break;
 40             }
 41         }
 42         p++;
 43     }
 44     return p;
 45 }
 47 unsigned long get_cpu_total_occupy(){ ///proc/stat文件从系统启动开始累计到当前时刻
 48     FILE *fd;
 49     char buff[1024]={0};
 50     Total_Cpu_Occupy_t t;
 51 
 52     fd=fopen("/proc/stat","r");
 53     if(nullptr==fd){
 54         return 0;
 55     }
 56 
 57     fgets(buff,sizeof(buff),fd);  //fd中的信息赋给buff
 58     char name[64]={0};
 59     sscanf(buff,"%s %ld %ld %ld %ld",name,&t.user,&t.nice,&t.system,&t.idle);//从字符串中读>    取指定格式的数据  %ld long整数 
 60     fclose(fd);
 61     
 62     return (t.user + t.nice + t.system + t.idle);
 63 }
 64 
 65 //获取进程的CPU时间
 66 unsigned long get_cpu_proc_occupy(unsigned int pid){
 67     
 68     char file_name[64]={0};
 69     Proc_Cpu_Occupy_t t;
 70     FILE *fd;
 71     char line_buff[1024]={0};
 72     sprintf(file_name,"/proc/%d/stat",pid);
 73     
 74     fd = fopen(file_name,"r");
 75     if(nullptr == fd){
 76         return 0;
 77     }
 78     
 79     fgets(line_buff,sizeof(line_buff),fd); 
 80     
 81     sscanf(line_buff,"%u",&t.pid); //%u 十进制无符号整数 
 82     const char *q =get_items(line_buff,PROCESS_TIME);
 83     sscanf(q,"%ld %ld %ld %ld",&t.utime,&t.stime,&t.cutime,&t.cstime);
 84     fclose(fd);
 85     
 86     return (t.utime + t.stime + t.cutime + t.cstime);                                       
 87 }
 90 //获取CPU占用率
 91 float get_proc_cpu(unsigned int pid){
 92     
 93     unsigned long totalcputime1,totalcputime2;
 94     unsigned long procputime1,procputime2;
 95     
 96     totalcputime1=get_cpu_total_occupy();
 97     procputime1=get_cpu_proc_occupy(pid);
 98  
 99     usleep(200000);//0.2s
100  
101     totalcputime2=get_cpu_total_occupy();
102     procputime2=get_cpu_proc_occupy(pid);
103     
104     float pcpu = 0.0;
105     if(0 != totalcputime2-totalcputime1){ 
106         pcpu=100.0 * (procputime2-procputime1)/(totalcputime2-totalcputime1);
107     }
108     
109     return pcpu;
110 }
113 //获取进程占用内存
114 unsigned int get_proc_mem(unsigned int pid){
115     
116     char file_name[64]={0};
117     FILE *fd;
118     char line_buff[512]={0};
119     sprintf(file_name,"/proc/%d/status",pid);
120     
121     fd =fopen(file_name,"r");
122     if(nullptr == fd){
123         return 0;
124     }
125     
126     char name[64];
127     int vmrss;
128     for (int i=0; i<VMRSS_LINE-1;i++){
129         fgets(line_buff,sizeof(line_buff),fd);
130     }
131     
132     fgets(line_buff,sizeof(line_buff),fd);
133     sscanf(line_buff,"%s %d",name,&vmrss);
134     fclose(fd);
135  
136     return vmrss;
137 }
139  
140 //获取进程占用虚拟内存
141 unsigned int get_proc_virtualmem(unsigned int pid){
142     
143     char file_name[64]={0};
144     FILE *fd;
145     char line_buff[512]={0};
146     sprintf(file_name,"/proc/%d/status",pid);
147     
148     fd =fopen(file_name,"r");
149     if(nullptr == fd){
150         return 0;
151     }
152     
153     char name[64];
154     int vmsize;
155     for (int i=0; i<VMSIZE_LINE-1;i++){
156         fgets(line_buff,sizeof(line_buff),fd);
157     }
158     
159     fgets(line_buff,sizeof(line_buff),fd);
160     sscanf(line_buff,"%s %d",name,&vmsize);
161     fclose(fd);
162  
163     return vmsize;
164 }
167 //进程本身
168 int get_pid(const char* process_name, const char* user = nullptr)//根据进程名获得pid
169 {
170     if(user == nullptr){
171         user = getlogin();  //若没有输入用户名,则认为用户名为当前登录名
172     }
173     
174     char cmd[512];
175     if (user){
176         sprintf(cmd, "pgrep %s -u %s", process_name, user); //cmd="pgrep process_name -u use    r" 返回进程ID
177     }
178  
179     FILE *pstr = popen(cmd,"r");    
180     
181     if(pstr == nullptr){
182         return 0;   
183     }
184  
185     char buff[512];
186     ::memset(buff, 0, sizeof(buff));
187     if(NULL == fgets(buff, 512, pstr)){//指定的流 stream 读取一行,并把它存储 
188         return 0;
189     }
190  
191     return atoi(buff); //返回整数
192 }
194 // 获取发送速率
195 static pid_t *childpid=nullptr;/*ptr to array allocated at run-time*/
196 static int maxfd; /*from our open_max(), {Prox openmax}*/
197 float readdata(int pid);
198 
199 FILE *popen2(const char *cmdstring, const char *type)
200 {
201      int i, pfd[2];
202      pid_t pid;
203      FILE *fp;
204      if(type[0] != 'r' && type[0]!='w' || type[1] != 0) {
205         errno=EINVAL;
206          return (nullptr);
207          }
208      if(childpid == nullptr) { /*first time throngh, allocate zeroed out array for child pid    s*/
209          maxfd = sysconf(_SC_OPEN_MAX);
210          if((childpid = (pid_t*)calloc(maxfd, sizeof(pid_t))) == nullptr)
211          return(nullptr);
212          }
213      if(pipe(pfd) < 0)
214     return(nullptr); //errno set by pipe()
215      if((pid = fork()) < 0)
216     return(nullptr); //error set by fork()
217      else if(pid==0) { /*child*/
218          if(*type == 'r') {
219              close(pfd[0]);
220              if(pfd[1] != STDOUT_FILENO) {
221                  dup2(pfd[1], STDOUT_FILENO);
222                  close(pfd[1]);
223                  }
224             } else {
225              close(pfd[1]);
226              if(pfd[0] != STDIN_FILENO) {
227                  dup2(pfd[0], STDIN_FILENO);
228                  close(pfd[0]);
229                  }
230             }
231          /*close all descriptiors in childpid*/                                             
232          for(i = 0; i < maxfd; i++)
233          if(childpid[i] > 0)
234          close(i);
235          execl(SHELL, "bash", "-c", cmdstring, (char *)0);
236          _exit(127);
237          }
238 
239      /*parent*/
240      if(*type == 'r') {
241          char lose(pfd[1]);
242          if((fp = fdopen(pfd[0], type)) == nullptr)
243          return (nullptr);
244          }else {
245          close(pfd[0]);
246          if((fp = fdopen(pfd[1], type)) == nullptr)
247          return (nullptr);
248          }
249      childpid[fileno(fp)] = pid; /*remember child pid for this fd*/
250      return(fp);
251 }
252 
253 int pclose2(FILE *fp)
254 {
255      int fd, stat;
256      pid_t pid;
257      //printf("hello>>>>>>>>>>>>>\n");
258      if(childpid == nullptr) /*popen() has never benn called*/
259      return (-1);
260 
261      fd = fileno(fp);
262      if((pid = childpid[fd]) == 0)
263      return (-1); //fp wasn't opened by popen()
264 
265      childpid[fd] = 0;
266      if(fclose(fp) == EOF)
267      return (-1);
268      if( kill(pid, SIGKILL) != 0) {
269          printf("kill failed\n");
270          perror("kill");
271          }
272      else {
273         // printf("%d killed\n", pid);
274          }
275      while(waitpid(pid, &stat, 0) < 0) {
276          if(errno != EINTR )                                                                
277              return (-1); /*error other than EINTR from waitpid()*/
278          }
279 
280      return(stat);
281 }
284 //输出发送速率到log.txt
285 float get_send( int pid)
286 {
287     char cmd[512]="sudo nethogs -a -t>log.txt";
288     //printf("cmd=%s\n",cmd);
289     FILE *pstr = popen2(cmd,"r");
290     if(nullptr == pstr){
291         printf("打开nethogs命令失败!\n");
292         return -1;
293     }
294     usleep(500000);
295     pclose2(pstr);
296     usleep(500000);
297     float read_rate;
298     read_rate = readdata(pid);
299 
300     return read_rate;
301 }
302 float readdata( int pid) //从log.txt中读取发送速率
303 {
304     //创建文件流,文件指针名=fopen(文件名,使用文件方式)打开失败则返回NULL;
305     FILE *fp=fopen("./log.txt","r");
306     //检测文件是否打开成功;
307     if(!fp){
308         printf("TXT打开失败!\n");
309         return -1; //返回异常
310     }
311     char name[10];
312     char third[10];
313     char readpid[5];
314     float sendrate,recerata; //用来储存收发速度
315     fscanf(fp, "%*c%*[^\n]%*c");
316     fscanf(fp, "%*c%*[^\n]%*c");
317     fscanf(fp, "%*c%*[^\n]%*c");
318     fscanf(fp, "%*c%*[^\n]%*c");
319     fscanf(fp, "%*c%*[^\n]%*c");
320     fscanf(fp, "%*c%*[^\n]%*c");
321     fscanf(fp, "%*c%*[^\n]%*c");                                                            
322     fscanf(fp, "%*c%*[^\n]%*c");
323     fscanf(fp, "%*c%*[^\n]%*c");
324     //fscanf(fp,"./%[^'/']/%[^'/']/%s %f %f\n",&name,&readpid,&third,&sendrate,&recerata);
325     //printf("pid=%d\n",pid);
326     while(fscanf(fp,"./%[^'/']/%[^'/']/%s %f %f\n",&name,&readpid,&third,&sendrate,&recerata    )>0){
327       //  printf("%s %s %s %lf %lf",&name,&readpid,&third,sendrate,recerata);
328         if(pid==atoi(readpid)){
329           //  printf("%s %s %s %lf %lf",&name,&readpid,&third,sendrate,recerata);
330             printf("成功读取发送速率!\n");
331             fclose(fp);
332             return sendrate;
333         }
334     }
335     printf("read sendrate fail!\n");
336     fclose(fp);
337 return 0;
338 }
339 
340 int main(int argc, char *argv[])
341 {
342   while(1){
343 
344     if(argc < 2){
345         printf("Usage:test <process_name> [user]\n");//调用格式:  ./getinfo 进程名
346         return 1;
347     }
348     
349     unsigned int pid=0;
350     
351     if(argc > 2){
352         pid = get_pid(argv[1],argv[2]);
353     }
354     else{
355         pid = get_pid(argv[1]);
356     }
357     
358     printf("pid=%d\n",pid);
359     printf("pcpu=%f\n",get_proc_cpu(pid));
360     printf("procmem=%d\n",get_proc_mem(pid));
361     printf("virtualmem=%d\n",get_proc_virtualmem(pid));                                     
362     printf("sendrate=%lf\n",get_send(pid));
363     printf("-----------------------------------------\n");
364     usleep(2000000);
365   }
367     return 0;
368 } 

编译:
在这里插入图片描述
运行:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值