📄 cuozuoxitongkechengsheji275913647.c
字号:
#include<gtk/gtk.h>#include<string.h>#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<dirent.h>#include<fcntl.h>#include<ctype.h>#include <pthread.h>#include <sys/types.h>#include<time.h>/*****定义一个结构,用来形成一个链表,每一个节点保存其利用率,用来绘制两分钟内内存和CPU的利用率*****/typedef struct mu_node{ int y; struct mu_node *next;}mm_cpu_node;/****定义两个链表的头节点在绘制CPU和内存曲线时,用来保存点的信息***/mm_cpu_node *cpu_head=NULL,*mm_head=NULL;/****创建四个全局变量,用来保存两个时刻所用CPU的总量,以及真正使用的量,以计算利用率***/float cpu_total[2]={0,0},cpu_used[2]={0.0,0.0};/******列表框定义为外部变量,以减少参数的传递,列表框中用来保存进程的有关信息*****/GtkWidget *clist; /****用来保存所选择的行号,用以在结束进程,以及显示详细信息时使用****/int S_ROW=10000;/****两个绘图区域,以及两个后端位图,用以绘制CPU以及内存利用率曲线*****/GtkWidget *pixmap[2]={NULL,NULL};GtkWidget *drawing_area[2]={NULL,NULL}; int count=0;/*********CPU曲线绘制链表中以及内存曲线绘制链表中节点的数目***********************/int mm_node_count=0;//内存绘制链表中结点的数目int cpu_node_count=0;/**********两个进度条,显示CPU和内存的利用率***************/GtkWidget *scl[2]; /*********定义一个标签,用以显示系统使用总时间(需要定时更新)********/GtkWidget *all_time_label;GtkWidget *status[3]; /*定义状态栏 */int COUNT_PID=0; /*系统中进程的总数*/GtkWidget *pidcountlab; /*用以显示系统中进程总数*/gint delete( GtkWidget *widget, /*该程序点击关闭后调用*/ GtkWidget *event, gpointer data ){ gtk_main_quit (); return FALSE;}/*刷新状态栏中时间信息的函数*/void refresh_status_bar_time(){ static char buf[22]=""; time_t timep; struct tm *p; time(&timep); p=localtime(&timep); guint i=gtk_statusbar_get_context_id(GTK_STATUSBAR(status[0]),buf); if(i>=0)gtk_statusbar_pop(GTK_STATUSBAR(status[0]),i); sprintf(buf," 当前时间:%d:%d%d:%d%d",p->tm_hour,p->tm_min/10,p->tm_min%10,p->tm_sec/10,p->tm_sec%10); gtk_statusbar_push(GTK_STATUSBAR(status[0]),i,buf); }/********刷新状态栏中内存使用量以及剩余量的函数************/void refresh_status_bar_mm(float used,float free){ static char buf_used[22]=""; static char buf_free[22]=""; guint i=gtk_statusbar_get_context_id(GTK_STATUSBAR(status[1]),buf_used); if(i>=0)gtk_statusbar_pop(GTK_STATUSBAR(status[1]),i); sprintf(buf_used," 已用内存:%.0fKB",used); gtk_statusbar_push(GTK_STATUSBAR(status[1]),i,buf_used); i=gtk_statusbar_get_context_id(GTK_STATUSBAR(status[2]),buf_free); if(i>=0)gtk_statusbar_pop(GTK_STATUSBAR(status[2]),i); sprintf(buf_free," 剩余内存:%.0fKB",free); gtk_statusbar_push(GTK_STATUSBAR(status[2]),i,buf_free); }/**读proc文件时调用的读文件函数****/gint read_file(char *filename,char *buf){ int sourcefd; int num; if((sourcefd=open(filename,002))==-1) { printf("error!"); return -1; } num=read(sourcefd,buf,100); buf[num]='\0'; close(sourcefd); return 0; }/*当需要读入的信息量很大时,则调用下面这个读文件函数(当需要把进程的详细信息读出来时)***/gint read_pidinfo(char *filename,char *buf){ int sourcefd; int num; if((sourcefd=open(filename,002))==-1) { printf("error!"); return -1; } num=read(sourcefd,buf,1000); buf[num]='\0'; close(sourcefd); return 0; }/*点击菜单,选择注销时调用的函数(尚未起用)**/gint logoff_computer( GtkWidget *widget, GtkWidget *event, gpointer data ){ return 0;}/**重启计算机的函数***/gint reboot_computer( GtkWidget *widget, GtkWidget *event, gpointer data ){ system("reboot"); return 0;}/*关机函数*/gint shutdown_computer( GtkWidget *widget, GtkWidget *event, gpointer data ){ system("halt -i"); return 0;}/*创建新任务的函数*/gint new_thread( GtkWidget *widget, GtkWidget *event, gpointer data ){ GtkWidget *d = gtk_dialog_new_with_buttons ("新建任务", NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); GtkWidget *entry_pid=gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY (entry_pid), "输入任务的全路径"); gtk_widget_show(entry_pid); gtk_container_add (GTK_CONTAINER (GTK_DIALOG(d)->vbox), entry_pid); gint result = gtk_dialog_run (GTK_DIALOG (d)); switch (result) { case GTK_RESPONSE_ACCEPT: system(gtk_entry_get_text(GTK_ENTRY (entry_pid))); break; default: break; } gtk_widget_destroy (d); return 0;}/***关于菜单项相关联的函数*****/gint help_about( GtkWidget *widget, GtkWidget *event, gpointer data ){ GtkWidget *dialog, *label; dialog = gtk_dialog_new_with_buttons ("查找进程", NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL); label = gtk_label_new ("本程序由计算机学院0309班 刘马良 饶远健两人合作完成\n完成时间:2006-03-02"); gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),label); gtk_widget_show(label); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); return 0;}/***显示进程详细信息的函数*************/gint more_info(GtkWidget *widget, GtkWidget *event, gpointer data ){ GtkWidget *d; char buffer[1000]; GtkWidget *b1,*b2; char s[20]={"/proc/"}; GtkWidget *table; int i,j; if(gtk_clist_get_selectable(GTK_CLIST(clist),S_ROW)==TRUE) { char *text; GtkWidget *d; d = gtk_dialog_new_with_buttons ("进程详细信息", NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL); gtk_window_resize(d,300,200); gtk_clist_get_text(GTK_CLIST(clist),S_ROW,1,&text); for(i=0;isspace(text[i]);i++); for(j=i,i=0;j<strlen(text);j++,i++) buffer[i]=text[j]; buffer[i]='\0'; strcat(s,buffer); strcat(s,"/status"); read_pidinfo(s,buffer); GtkWidget *label=gtk_label_new(buffer); gtk_widget_show(label); buffer[100]=' ';buffer[102]=' '; puts(buffer); printf("\n%d",strlen(buffer)); gtk_container_add (GTK_CONTAINER (GTK_DIALOG(d)->vbox),label); gtk_widget_show(d); gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); } return TRUE; }/****从缓冲区中筛选某一信息的函数******/void select_string(char *buf,char *sel) /*从buf区中筛选出sel字符串后的内容,以换行符作结束*/{ char buff[200]; char select[100]; int i,j; strcpy(buff,buf); strcpy(select,sel); for(i=0;i<strlen(buff);i++) /*匹配字符串*/ { for(j=0;j<strlen(select);j++) {if(buff[i]!=select[j]) break; else i++; } if(j>=strlen(select)) { i=i-j; break; }else{ i=i-j; j=0; } } i+=strlen(select); for(j=i;isspace(buff[j])||buff[j]==':';j++); for(i=j;!isspace(buff[i])||buff[i]==' ';i++) buf[i-j]=buff[i]; buf[i-j]='\0'; return; } /****创建一个标签,并在其上面输出______________________********/void draw_line(GtkWidget *table,gint l,gint r,gint t,gint b){ GtkWidget *label=gtk_label_new(" _____________________________________________________________________"); gtk_widget_show(label); gtk_table_attach_defaults(GTK_TABLE(table),label,l,r,t,b); return; } /*********通过进程号获取进程名***************/void get_pidname(char *spid,char *buff){ char proc_name[258]; char buf[50]; strcpy(proc_name,"/proc/"); const char *noname="no name"; int i,j; strcat(proc_name,spid); strcat(proc_name,"/status"); read_file(proc_name,buf); select_string(buf,"Name"); strcpy(buff,buf);}/****获取进程的父进程号***/void get_ppid(char *spid,char *buff){ char proc_name[258]; char buf[50]; strcpy(proc_name,"/proc/"); const char *noname="no name"; int i,j; strcat(proc_name,spid); strcat(proc_name,"/status"); read_file(proc_name,buf); select_string(buf,"PPid"); strcpy(buff,buf);}/***获取进程状态*************/void get_pidstate(char *spid,char *buff){ char proc_name[258]; char buf[50]; strcpy(proc_name,"/proc/"); const char *noname="no name"; int i,j; strcat(proc_name,spid); strcat(proc_name,"/status"); read_file(proc_name,buf); select_string(buf,"State"); strcpy(buff,buf);}/***刷新列表框中的进程列表****/gboolean refresh_pidlist(){ char s[30]; int count,i; count=0; DIR *dirp; struct dirent *direntp; char *s1[]={" "," ", " "," "}; char sformat[300]=" "; char ssformat[100]; strcpy(sformat," "); dirp=opendir("/proc"); gtk_clist_freeze(GTK_CLIST(clist)); /**冻结列表框,以提高更新速度***/ while(dirp!=NULL&(direntp=readdir(dirp))!=NULL)/**读/PROC目录***/ { strcpy(s,direntp->d_name); for(i=0;i<strlen(s);i++) /**判断文件名是否全是数字****/ if(!(isdigit(s[i]))) break; if(i==strlen(s)) /*如果文件名全是数字,说明是一个进程的目录***/ { count++; if(COUNT_PID<count) /*如果当前时刻进程数大于上一时刻进程数***/ { COUNT_PID=count; /**更新进程总数**/ i=gtk_clist_append(GTK_CLIST(clist),s1);/**新增加一行**/ }else i=count-1; /*否则,不更新进程数以及新增行,直接修改对应的行中的信息***//******************下面这一程序段为修改列表框中行,列中的信息**************/ get_pidname(s,sformat); gtk_clist_set_text(GTK_CLIST(clist),i,0,sformat); strcpy(sformat," "); strcat(sformat,s); gtk_clist_set_text(GTK_CLIST(clist),i,1,sformat); get_ppid(s,sformat); strcpy(ssformat," "); strcat(ssformat,sformat); gtk_clist_set_text(GTK_CLIST(clist),i,2,ssformat); get_pidstate(s,sformat); strcpy(ssformat," "); strcat(ssformat,sformat); gtk_clist_set_text(GTK_CLIST(clist),i,3,ssformat); strcpy(sformat," "); /**************************************************************************/ } } /***进程目录读取完毕,判断该时刻进程总数是否小于上一时刻,如果小于,则需要删除多余的行****/ if(count<COUNT_PID) { for(i=count;i<COUNT_PID;i++) gtk_clist_remove(GTK_CLIST(clist),i); COUNT_PID=count; } /****************************************************************************************/ gtk_clist_thaw(GTK_CLIST(clist));/*解冻列表框**/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -