代碼 | C語言根據可執(zhí)行文件名獲取進程運行信息
如下示例可根據可執(zhí)行文件名獲得線程數、虛擬內存占用大小、物理內存占用大小、進程PID、CPU占用率和進程啟動次數等信息。
1.程序源碼
main.c:
#include?
#include?
#include?
#include?
#include?"proc_info.h"
?
int?main(int?argc,?char?*argv[])
{
?
?PROCESS_INFO?table={0};
?strcpy(table.proc_name,"test");?//監(jiān)控的進程名
?sys_proc_info_init(?&table,?1);?//系統(tǒng)監(jiān)控初始化
?while(1)
?{
??sleep(1);
??printf("-----------------------\n");
??printf("proc_name?=?%s\n",table.proc_name);
??printf("state?=?%d\n",table.state);
??printf("thread_num?=?%d\n",table.thread_num);
??printf("pid?=?%d\n",table.pid);
??printf("rss?=?%d\n",table.rss);
??printf("vss?=?%d\n",table.vss);
??printf("cpu?=?%.2lf\n",table.cpu);
??printf("reset_times?=?%d\n\n",table.reset_times);
?}
??
?sys_proc_info_uninit();
?return?0;?
}
proc_info.c:
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?"proc_info.h"
?
static?PROCESS_INFO?*g_proc_ptr?=?NULL;?
static?int?g_proc_num?=?0;
?
?
/*******************?參數信息?*************************/
static?struct?proc_info?**old_procs,?**new_procs;
static?int?num_old_procs,?num_new_procs;
static?struct?proc_info?*free_procs;
static?int?num_used_procs,?num_free_procs;
static?int?max_procs,?delay,?iterations,?threads;
static?struct?cpu_info?old_cpu,?new_cpu;
static?pthread_t?thread_id;??//線程ID
static?int?running_flag?=?0;
?
?
/*******************?本地函數聲明?*************************/
static?struct?proc_info?*alloc_proc(void);
static?void?free_proc(struct?proc_info?*proc);
static?void?read_procs(void);
static?int?read_stat(char?*filename,?struct?proc_info?*proc);
static?void?add_proc(int?proc_num,?struct?proc_info?*proc);
static?int?read_cmdline(char?*filename,?struct?proc_info?*proc);
static?int?read_status(char?*filename,?struct?proc_info?*proc);
static?void?update_procs_state(void);
static?struct?proc_info?*find_old_proc(pid_t?pid,?pid_t?tid);
static?void?free_old_procs(void);
static?int?(*proc_cmp)(const?void?*a,?const?void?*b);
static?int?proc_cpu_cmp(const?void?*a,?const?void?*b);
static?int?proc_vss_cmp(const?void?*a,?const?void?*b);
static?int?proc_rss_cmp(const?void?*a,?const?void?*b);
static?int?proc_thr_cmp(const?void?*a,?const?void?*b);
static?int?numcmp(long?long?a,?long?long?b);
?
void?*sys_info_proc(void?*arg)??//系統(tǒng)信息處理線程
{
?
?int?i;
?num_used_procs?=?0;
?num_free_procs?=?0;
?max_procs?=?0;
?delay?=?3;
?iterations?=?-1;
?proc_cmp?=?&proc_cpu_cmp;
??
?if?(threads?&&?proc_cmp?==?&proc_thr_cmp)
?{
??fprintf(stderr,?"Sorting?by?threads?per?thread?makes?no?sense!\n");
??exit(EXIT_FAILURE);
?}
??
?free_procs?=?NULL;
?num_new_procs?=?num_old_procs?=?0;
?new_procs?=?old_procs?=?NULL;
?read_procs();
?
?while(running_flag)
?{
??old_procs?=?new_procs;
??num_old_procs?=?num_new_procs;
??memcpy(&old_cpu,?&new_cpu,?sizeof(old_cpu));
??
??sleep(delay);
??
??read_procs();
??update_procs_state();
??free_old_procs();
?}
?
?return?NULL;
}
?
int?sys_proc_info_init(PROCESS_INFO?*process_array,?int?num)?//系統(tǒng)進程信息初始化
{
?if(process_array?!=?NULL?&&?num?!=?0)
?{
??g_proc_ptr?=?process_array;
??g_proc_num?=?num;
?}
?else
?{
??printf("----sys_proc_info_init?param?fail!!\n");
??return?-1;
?}
??
?
?running_flag?=?1;
?int?ret?=?pthread_create(&thread_id,?NULL,sys_info_proc,NULL);
?if(ret?!=?0)
?{
??printf("----create?sys_info_proc?pthread?fail!!\n");
??return?-1;
?}
?
?return?0;
}
?
int?sys_proc_info_uninit()?//系統(tǒng)進程信息資源釋放
{
?running_flag?=?0;
?if(thread_id?!=?0)
?{
??pthread_join(thread_id,?NULL);
?}
}
?
?
static?struct?proc_info?*alloc_proc(void)
{
????struct?proc_info?*proc;
????if?(free_procs)?
?{
????????proc?=?free_procs;
????????free_procs?=?free_procs->next;
????????num_free_procs--;
????}?
?else?
?{
????????proc?=?malloc(sizeof(*proc));
????????if?(!proc)?
???printf("Could?not?allocate?struct?process_info.\n");
????}
????num_used_procs++;
????return?proc;
}
?
static?void?free_proc(struct?proc_info?*proc)
{
????proc->next?=?free_procs;
????free_procs?=?proc;
????num_used_procs--;
????num_free_procs++;
}
??
static?void?read_procs(void)
{
????DIR?*proc_dir,?*task_dir;
????struct?dirent?*pid_dir,?*tid_dir;
????char?filename[64];
????FILE?*file;
????int?proc_num;
????struct?proc_info?*proc;
????pid_t?pid,?tid;
????int?i;
????proc_dir?=?opendir("/proc");
????if?(!proc_dir)?
??printf("Could?not?open?/proc.\n");
?
????new_procs?=?calloc(INIT_PROCS?*?(threads???THREAD_MULT?:?1),?sizeof(struct?proc_info?*));
????num_new_procs?=?INIT_PROCS?*?(threads???THREAD_MULT?:?1);
?
????file?=?fopen("/proc/stat",?"r");
????if?(!file)
??printf("Could?not?open?/proc/stat.\n");
?
????fscanf(file,?"cpu??%lu?%lu?%lu?%lu?%lu?%lu?%lu",?&new_cpu.utime,?&new_cpu.ntime,?&new_cpu.stime,
????????????&new_cpu.itime,?&new_cpu.iowtime,?&new_cpu.irqtime,?&new_cpu.sirqtime);
????fclose(file);
?
????proc_num?=?0;
????while?((pid_dir?=?readdir(proc_dir)))
?{
????????if?(!isdigit(pid_dir->d_name[0]))
????????????continue;
?
????????pid?=?atoi(pid_dir->d_name);
????????struct?proc_info?cur_proc;
????????if?(!threads)?{
????????????proc?=?alloc_proc();
????????????proc->pid?=?proc->tid?=?pid;
????????????sprintf(filename,?"/proc/%d/stat",?pid);
????????????read_stat(filename,?proc);
?
????????????sprintf(filename,?"/proc/%d/cmdline",?pid);
????????????read_cmdline(filename,?proc);
?
????????????sprintf(filename,?"/proc/%d/status",?pid);
????????????read_status(filename,?proc);
??
????????????proc->num_threads?=?0;
????????}?
??else?
??{
????????????sprintf(filename,?"/proc/%d/cmdline",?pid);
????????????read_cmdline(filename,?&cur_proc);
?
????????????sprintf(filename,?"/proc/%d/status",?pid);
????????????read_status(filename,?&cur_proc);
????????????
????????????proc?=?NULL;
????????}
?
????????sprintf(filename,?"/proc/%d/task",?pid);
????????task_dir?=?opendir(filename);
????????if?(!task_dir)?continue;
?
????????while?((tid_dir?=?readdir(task_dir)))
??{
????????????if?(!isdigit(tid_dir->d_name[0]))
????????????????continue;
?
????????????if?(threads)?{
????????????????tid?=?atoi(tid_dir->d_name);
?
????????????????proc?=?alloc_proc();
?
????????????????proc->pid?=?pid;?proc->tid?=?tid;
?
????????????????sprintf(filename,?"/proc/%d/task/%d/stat",?pid,?tid);
????????????????read_stat(filename,?proc);
????
????????????????strcpy(proc->name,?cur_proc.name);
????????????????proc->uid?=?cur_proc.uid;
????????????????proc->gid?=?cur_proc.gid;
?
????????????????add_proc(proc_num++,?proc);
????????????}?else?{
????????????????proc->num_threads++;
????????????}
????????}
?
????????closedir(task_dir);
????????
????????if?(!threads)
????????????add_proc(proc_num++,?proc);
????}
?
????for?(i?=?proc_num;?i?????????new_procs[i]?=?NULL;
?
????closedir(proc_dir);
}
?
static?int?read_stat(char?*filename,?struct?proc_info?*proc)
{
????FILE?*file;
????char?buf[MAX_LINE],?*open_paren,?*close_paren;
????int?res,?idx;
?
????file?=?fopen(filename,?"r");
????if?(!file)?return?1;
????fgets(buf,?MAX_LINE,?file);
????fclose(file);
?
????/*?Split?at?first?'('?and?last?')'?to?get?process?name.?*/
????open_paren?=?strchr(buf,?'(');
????close_paren?=?strrchr(buf,?')');
????if?(!open_paren?||?!close_paren)?return?1;
?
????*open_paren?=?*close_paren?=?'\0';
????strncpy(proc->tname,?open_paren?+?1,?THREAD_NAME_LEN);
????proc->tname[THREAD_NAME_LEN-1]?=?0;
????
????/*?Scan?rest?of?string.?*/
????sscanf(close_paren?+?1,?"?%c?%*d?%*d?%*d?%*d?%*d?%*d?%*d?%*d?%*d?%*d?"
?????????????????"%lu?%lu?%*d?%*d?%*d?%*d?%*d?%*d?%*d?%lu?%ld",
?????????????????&proc->state,?&proc->utime,?&proc->stime,?&proc->vss,?&proc->rss);
????return?0;
}
?
static?void?add_proc(int?proc_num,?struct?proc_info?*proc)
{
????int?i;
?
????if?(proc_num?>=?num_new_procs)?{
????????new_procs?=?realloc(new_procs,?2?*?num_new_procs?*?sizeof(struct?proc_info?*));
????????if?(!new_procs)?
???printf("Could?not?expand?procs?array.\n");
????????for?(i?=?num_new_procs;?i?2?*?num_new_procs;?i++)
????????????new_procs[i]?=?NULL;
????????num_new_procs?=?2?*?num_new_procs;
????}
????new_procs[proc_num]?=?proc;
}
?
static?int?read_cmdline(char?*filename,?struct?proc_info?*proc)
{
????FILE?*file;
????char?line[MAX_LINE];
?
????line[0]?=?'\0';
????file?=?fopen(filename,?"r");
????if?(!file)?return?1;
????fgets(line,?MAX_LINE,?file);
????fclose(file);
????if?(strlen(line)?>?0)?{
????????strncpy(proc->name,?line,?PROC_NAME_LEN);
????????proc->name[PROC_NAME_LEN-1]?=?0;
????}?else
????????proc->name[0]?=?0;
????return?0;
}
?
static?int?read_status(char?*filename,?struct?proc_info?*proc)
{
????FILE?*file;
????char?line[MAX_LINE];
????unsigned?int?uid,?gid;
?
????file?=?fopen(filename,?"r");
????if?(!file)?return?1;
????while?(fgets(line,?MAX_LINE,?file))?{
????????sscanf(line,?"Uid:?%u",?&uid);
????????sscanf(line,?"Gid:?%u",?&gid);
????}
????fclose(file);
????proc->uid?=?uid;?proc->gid?=?gid;
????return?0;
}
?
static?void?update_procs_state(void)
{
????int?i=0,j=0;
????struct?proc_info?*old_proc,?*proc;
????unsigned?long?total_delta_time;
????struct?passwd?*user;
????struct?group?*group;
????char?*user_str,?user_buf[20];
????char?*group_str,?group_buf[20];
?
????for?(i?=?0;?i??{
????????if?(new_procs[i])
??{
????????????old_proc?=?find_old_proc(new_procs[i]->pid,?new_procs[i]->tid);
????????????if?(old_proc)
???{
????????????????new_procs[i]->delta_utime?=?new_procs[i]->utime?-?old_proc->utime;
????????????????new_procs[i]->delta_stime?=?new_procs[i]->stime?-?old_proc->stime;
????????????}?
???else?
???{
????????????????new_procs[i]->delta_utime?=?0;
????????????????new_procs[i]->delta_stime?=?0;
????????????}
????????????new_procs[i]->delta_time?=?new_procs[i]->delta_utime?+?new_procs[i]->delta_stime;
????????}
????}
?
????total_delta_time?=?(new_cpu.utime?+?new_cpu.ntime?+?new_cpu.stime?+?new_cpu.itime
????????????????????????+?new_cpu.iowtime?+?new_cpu.irqtime?+?new_cpu.sirqtime)
?????????????????????-?(old_cpu.utime?+?old_cpu.ntime?+?old_cpu.stime?+?old_cpu.itime
????????????????????????+?old_cpu.iowtime?+?old_cpu.irqtime?+?old_cpu.sirqtime);
?
????qsort(new_procs,?num_new_procs,?sizeof(struct?proc_info?*),?proc_cmp);
?
?int?*state_table?=?(int?*)malloc(g_proc_num*sizeof(int));
?memset(state_table,?0,?g_proc_num*sizeof(int));//清空監(jiān)控程序狀態(tài)
?
????for?(i?=?0;?i??{
????????proc?=?new_procs[i];
??
????????if?(!proc?||?(max_procs?&&?(i?>=?max_procs)))
????????????break;
????????user??=?getpwuid(proc->uid);
????????group?=?getgrgid(proc->gid);
????????if?(user?&&?user->pw_name)?{
????????????user_str?=?user->pw_name;
????????}?else?{
????????????snprintf(user_buf,?20,?"%d",?proc->uid);
????????????user_str?=?user_buf;
????????}
????????if?(group?&&?group->gr_name)?{
????????????group_str?=?group->gr_name;
????????}?else?{
????????????snprintf(group_buf,?20,?"%d",?proc->gid);
????????????group_str?=?group_buf;
????????}
??
??for(j=0;?j??{
???if(?!strcmp((char?*)&proc->tname,?(char?*)&g_proc_ptr[j].proc_name)?)
???{
????g_proc_ptr[j].cpu?=?proc->delta_time?*?100.0?/?total_delta_time;?//CPU使用率
????if(proc->pid?!=?g_proc_ptr[j].pid)
????{
?????g_proc_ptr[j].reset_times++;??//程序啟動次數
?????g_proc_ptr[j].pid?=?proc->pid;??//進程ID
????}
????g_proc_ptr[j].vss?=?proc->vss?/?1024;???//虛擬內存
????g_proc_ptr[j].rss?=?proc->rss?*?getpagesize()?/?1024;?//物理內存
????g_proc_ptr[j].thread_num?=?proc->num_threads;???//線程數
????state_table[j]?=?1;?//進程信息有效
???}
??}
?}
?
?for(j=0;?j?{
??g_proc_ptr[j].state?=?state_table[j];?//進程狀態(tài)??0?進程不存在????????1進程存在
?}
?
?if(NULL?!=?state_table)
?{
??free(state_table);
??state_table?=?NULL;
?}
}
?
static?struct?proc_info?*find_old_proc(pid_t?pid,?pid_t?tid)
{
????int?i;
????for?(i?=?0;?i?????????if?(old_procs[i]?&&?(old_procs[i]->pid?==?pid)?&&?(old_procs[i]->tid?==?tid))
????????????return?old_procs[i];
?
????return?NULL;
}
?
static?void?free_old_procs(void)
{
????int?i;
????for?(i?=?0;?i?????????if?(old_procs[i])
????????????free_proc(old_procs[i]);
????free(old_procs);
}
?
static?int?proc_cpu_cmp(const?void?*a,?const?void?*b)
{
????struct?proc_info?*pa,?*pb;
?
????pa?=?*((struct?proc_info?**)a);?pb?=?*((struct?proc_info?**)b);
?
????if?(!pa?&&?!pb)?return?0;
????if?(!pa)?return?1;
????if?(!pb)?return?-1;
?
????return?-numcmp(pa->delta_time,?pb->delta_time);
}
?
static?int?proc_vss_cmp(const?void?*a,?const?void?*b)
{
????struct?proc_info?*pa,?*pb;
?
????pa?=?*((struct?proc_info?**)a);?pb?=?*((struct?proc_info?**)b);
?
????if?(!pa?&&?!pb)?return?0;
????if?(!pa)?return?1;
????if?(!pb)?return?-1;
?
????return?-numcmp(pa->vss,?pb->vss);
}
?
static?int?proc_rss_cmp(const?void?*a,?const?void?*b)
{
????struct?proc_info?*pa,?*pb;
?
????pa?=?*((struct?proc_info?**)a);?pb?=?*((struct?proc_info?**)b);
?
????if?(!pa?&&?!pb)?return?0;
????if?(!pa)?return?1;
????if?(!pb)?return?-1;
?
????return?-numcmp(pa->rss,?pb->rss);
}
?
static?int?proc_thr_cmp(const?void?*a,?const?void?*b)
{
????struct?proc_info?*pa,?*pb;
?
????pa?=?*((struct?proc_info?**)a);?pb?=?*((struct?proc_info?**)b);
?
????if?(!pa?&&?!pb)?return?0;
????if?(!pa)?return?1;
????if?(!pb)?return?-1;
?
????return?-numcmp(pa->num_threads,?pb->num_threads);
}
?
static?int?numcmp(long?long?a,?long?long?b)
{
????if?(a?return?-1;
????if?(a?>?b)?return?1;
????return?0;
}
proc_info.h:
/******************************************************************************
***?文?件?名??:?proc_info.h
***?作???者??:?fangye
***?生成日期??:?2019年3月?星期二
***?功能描述??:?獲取系統(tǒng)進程信息
*******************************************************************************/
#ifndef?__PROC_INFO_H__
#define?__PROC_INFO_H__
?
#ifdef?__cplusplus
extern?"C"{
#endif?/*?__cplusplus?*/
?
?
#define?PROC_NAME_LEN?64
#define?THREAD_NAME_LEN?32
#define?MAX_LINE?256
#define?INIT_PROCS?50
#define?THREAD_MULT?8
?
struct?cpu_info?{
????unsigned?long?utime,?ntime,?stime,?itime;
????unsigned?long?iowtime,?irqtime,?sirqtime;
};
?
struct?proc_info?{
????struct?proc_info?*next;
????pid_t?pid;
????pid_t?tid;
????uid_t?uid;
????gid_t?gid;
????char?name[PROC_NAME_LEN];
????char?tname[THREAD_NAME_LEN];
????char?state;
????unsigned?long?utime;
????unsigned?long?stime;
????unsigned?long?delta_utime;
????unsigned?long?delta_stime;
????unsigned?long?delta_time;
????long?vss;
????long?rss;
????int?num_threads;
????char?policy[32];
};
?
struct?proc_list?{
????struct?proc_info?**array;
????int?size;
};
?
typedef?struct?_PROCESS_INFO
{
?char?proc_name[PROC_NAME_LEN];
?int?state;???//運行狀態(tài)?0未運行??????????1運行中
?int?thread_num;??//線程數
?int?vss;???//虛擬內存
?int?rss;???//物理內存
?int?pid;???//進程ID
?int?reset_times;?//啟動次數
?double?cpu;???//CPU使用率
}PROCESS_INFO;
?
?
?
?
extern?int?sys_proc_info_init();?//系統(tǒng)進程信息初始化
?
extern?int?sys_proc_info_uninit();?//系統(tǒng)進程信息資源釋放
?
?
?
#ifdef?__cplusplus
}
#endif?/*?__cplusplus?*/
?
#endif?/*?__PROC_INFO_H__?*/
2.編譯
由于用到了線程,編譯需要鏈接pthread庫.。
gcc?main.c?proc_info.c?-o?test?-lpthread
3.測試結果

作者:fangye945a
原文鏈接:https://blog.csdn.net/fangye945a/article/details/88833764
本文來源網絡,免費傳達知識,版權歸原作者所有。如涉及作品版權問題,請聯系我進行刪除。
???????????????? ?END ?????????????????
評論
圖片
表情
