了解/proc 文件的特点和使用方法,监控系统状态,显示系统中若干部件的使用
情 况,用图形界面显示系统监控状态。
主要参考书目:<>,百度,google
这个任务管理器是参考着 windows 下的任务管理器和老师的要求做的。对于整体布局是
用 GTK 编写的,中间用到了常用的构件和容器比如:菜单栏,对话框,状态栏,盒子,
滚动条,标签,notebook 等,并且为在显示内存信息和进程信息看起来比较好看我还
用到了 GtkListStore、 GtkTreeViewColumn 和 gtkTreelter 等构件。因为过程有些复
杂我在关键部位进行了注释。大致布局是先创建窗口,之后创建表格,上面是一个菜单
栏,包括三个菜单,并且每个菜单下设有子菜单(关闭窗口,关机、重启、注销,关于
本任务管理器的介绍);下面和右侧是两个状态栏分别显示系统启动时间、系统运行时
间、总进程数、CPU 利用率,MEM 利用率,swap 利用率(实时显示则用 gtk_timeout_add
调用回调函数来达到每隔一段时间更新显示);中间是一个 notebook,期间设有五个页
面分别显示 cpu 信息,mem 信息,硬盘信息,进程信息,系统信息,mem 信息中用到了 树
型列表构件,可以手动刷新,在进程信息页中可以手动刷新和手动杀死一个进程。
读取/proc 文件信息:
从 /proc/stat 读 取 cpu 各 状 态 的 时 间 , 从 而 通 过 cpu_rate=
100*(user+nice+system)/(float)(user+nice+system+idle)得到 cpu 的利用率
从/proc/meminfo 读取内存总量和可用内存,利用 1-MemFree/MemTotal 得到 Mem 的利
用率
从/proc 这个目录下读取数字文件夹的数量,既是进程总数
从/proc/meminfo 读取内存信息
从/proc/进程号/status 读取进程名,PID 及状态,/proc/进程号/statm 读取进程占用
内存大小
从/proc/partitions 读取硬盘信息
从/proc/sys/kernel/hostanme 读取主机名
从/proc/cpuinfo 读取 cpu 信息
从/proc/version 中读取操作系统类型、内核版本、gcc 版本
为了格式化显示这些读取的信息,使用了 strtok 字符串分割函数,sprintf 函数可
以从某种规则中读取出自己需要的字符串,sscanf 函数则是连接两个字符串最好的
操作参数。
源代码:
编译:gcc -o os os.c
运行:./os
`pkg-config
--cflags
--libs
gtk+-2.0`
#define GTK_ENABLE_BROKEN
#include
#include
#include"dirent.h"
#include"unistd.h"
#include"sys/file.h"
#include"fcntl.h"
#include"string.h"
#include"time.h"
#include"math.h"
//图形点密度
//最大进程数目
#include
#include
#include
#define DENSITY 100
#define PMAX
100
enum
{
//进程名列
NAME_COLUMN,
PID_COLUMN,
//进程 PID 列
STATUS_COLUMN,//进程状态列
CPU_COLUMN,
//CPU 信息列
MEMORY_COLUMN,//内存信息列
NP_COLUMNS
};
enum
{
MAJOR_COLUMN,//分区主号
MINOR_COLUMN,//分区次要号
BLOCK_COLUMN,//块大小
NAME2_COLUMN,//分区名称
NB_COLUMNS
};
enum
{
NAME3_COLUMN,//分类
SIZE_COLUMN,//所占内存大小
KB_COLUMN,
NM_COLUMNS
};
struct Process{
char name[25];
char pro_id[10];
char cpu_take[10];
char mem_take[10];
}pro[200];
float cpu_rate,mem_rate,swap_rate;
char *title[6]={" 资源信息 "," 内存信息 "," 进程信息 "," 磁盘信息 "," 系统信息 ","说明
"};
gdouble fuser = 0;
//先前 CPU 使用信息
gdouble ftotal = 0; //先前 CPU 使用总量
gdouble total = 0;
gdouble pfuser[PMAX];
//当前进程总数
gdouble rate = 0;
//cpu 使用率
*info;
GtkWidget *window;
GtkWidget *notebook;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *info_label;
GString
GtkWidget *status_bar0;
GtkWidget *cpu_draw_area;
GtkWidget *mem_draw_area;
GtkWidget *mem_label;
GtkWidget *swap_label;
GtkWidget *scrolled_window;
GtkListStore *process_store;
GtkListStore *disk_store;
GtkListStore *mem_store;
GtkWidget *mem_bar;
GtkWidget *cpu_bar;
GtkWidget *swap_bar;
GtkWidget *ptree_view;
GtkWidget *btree_view;
GtkWidget *mtree_view;
GtkCellRenderer *renderer;//用于显示 tree view 中的每个列标题
GtkCellRenderer *drenderer;
GtkCellRenderer *mrenderer;
GtkTreeViewColumn *column;//tree view 控件列数
GtkTreeViewColumn *dcolumn;
GtkTreeViewColumn *mcolumn;
GtkWidget *prefresh_button,*pdelete_button; //刷新进程按钮和结束进程按钮
GtkWidget *main_vbox;
GtkWidget *text;
GtkWidget *table;
GtkWidget *table1[5];//定义表格
GtkWidget *frame[5];//定义框架
GtkWidget *frame0;
GtkWidget *ptree_view;
GtkWidget
*button[6],*label1,*cpu_rate_label,*process_label,*mem_rate_label,*time_label,*swap_rate_la
bel,*start_time_label,
*run_time_label;//定义标签
gint length;
int mem_flag,pro_flag;//定义两个标志变量,用来判断是否结束回调函数
GtkWidget *CreateMenuItem(GtkWidget *,char *);//创建菜单项函数
GtkWidget *CreateMenuFile(GtkWidget *);//创建菜单 File 函数
GtkWidget *CreateMenuShutDown(GtkWidget *);//创建菜单 Shutdown 函数
GtkWidget *CreateMenuHelp(GtkWidget *);//创建菜单 Help 函数
void show_dialog (gchar *, gchar *);
void get_cpu_info (GString *);
void get_os_info (GString *);
void draw_cpu_load_graph (void);
void draw_mem_load_graph (void);
gint cpu_rate_ava(void);
gint mem_rate_ava(void);
gint swap_rate_ava(void);
gint process_num(void);
gint mem_timeout(void);
gint pro_timeout(void);
gint start_time(void);
gint sys_time(void);
void get_process_info (GtkListStore *);
void get_disk_info (GtkListStore *);
void prefresh_button_clicked (gpointer data);
void prefresh_button_clicked2 (gpointer data);
void pdelete_button_clicked (gpointer data);
gboolean cpu_configure_event (GtkWidget *, GdkEventConfigure *, gpointer);
gboolean cpu_expose_event (GtkWidget *, GdkEventExpose *, gpointer);
gboolean mem_configure_event (GtkWidget *, GdkEventConfigure *, gpointer);
gboolean mem_expose_event (GtkWidget *, GdkEventExpose *, gpointer);
gboolean load_graph_refresh (gpointer data);
gboolean get_cpu_rate (gpointer data);
void cpu_button_clicked(void);
void mem_button_clicked(void);
void pro_button_clicked(void);
void disk_button_clicked(void);
void sys_button_clicked(void);
int select_name(char name[]){
//查找名字是否是数字
int i;
for(i=0;name[i]!=0;i++)
if(isalpha(name[i])||name[i]=='.')
return 0;
return 1;
}
void delete_event(GtkWidget *window,gpointer data){//回调函数,退出窗口管理程序
gtk_main_quit();
}
void restart(GtkWidget *window,gpointer data){//回调函数,注销
system("reboot");
}
void logout(GtkWidget *window,gpointer data){//回调函数,重启
system("logout");
}
void shutdown(GtkWidget *window,gpointer data){//回调函数,关机
system("halt");
}
void aboutSysMo(GtkWidget *window,gpointer data){//输出有关 gtk 的信息
GtkWidget *dialog,*label,*label2,*dtable,*text;
dialog=gtk_dialog_new();
gtk_widget_set_usize(dialog, 300, 300);
gtk_container_set_border_width(GTK_CONTAINER(dialog),5);//设置窗口边框宽度
dtable=gtk_table_new(11,10,TRUE);//创建表格 11 行*10 列
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),dtable, TRUE, TRUE, 0);
gtk_widget_show(dtable);//显示表格
label=gtk_label_new("关于任务管理器");
gtk_table_attach_defaults(GTK_TABLE(dtable),label,0,10,0,1);
gtk_widget_show (label);
label2=gtk_label_new("主要介绍:\n1.进程情况(进程总数、进程名称、\n 进程所
占 cpu 和内存率、进程状态和 PID)\n2.CPU 状态(用户占用、系统占用、\n 优先进程占用、
闲置进程占用)\n3.内存状态(平均可用内存、已用内存、\n 空闲内存、共享内存、缓存
使用内存)\n4.用户状态(登录帐号、终端名称、远程主机名、\n 登录时间、空闲时间、
当前正在运行进程的命令行)\n ");
gtk_table_attach_defaults(GTK_TABLE(dtable),label2,0,10,1,11);
gtk_widget_show (label2);
gtk_widget_show(dialog);
}
int main(int argc,char *argv[]){
gint i;
int v,v0;
GtkWidget *label1,*label2,*label;
GtkWidget *label0[5];
int timer;
gpointer date,data;
gdouble value1,value2;
gpointer gdata;
pro_flag=1;
mem_flag=0;
GtkWidget *label3;
GtkWidget *button1;
GtkWidget *vscrollbar,*hscrollbar;//定义滚动条
GtkWidget *MenuBar;//定义菜单栏
GtkWidget *MenuItemFile,*MenuItemShutDown,*MenuItemHelp;
gtk_set_locale ();
gtk_init(&argc,&argv);//在任何构件生成之前完成
memset (pfuser, 0 ,sizeof (pfuser));
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗口
gtk_window_set_title(GTK_WINDOW(window),"任务管理器");//设置窗口标题
gtk_widget_set_usize(window, 600, 500);//设置窗口大小
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);// 窗口大小可改变(TRUE)
gtk_container_set_border_width(GTK_CONTAINER(window),5);//设置窗口边框宽度
gtk_widget_show(window);//显示窗口
table=gtk_table_new(12,12,TRUE);//创建表格 12 行*10 列
text=gtk_text_new(NULL,NULL);
gtk_widget_show(table);//显示表格
gtk_container_add(GTK_CONTAINER(window),table);//将 table 装进窗口
notebook=gtk_notebook_new();
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook),GTK_POS_TOP);
gtk_table_attach_defaults (GTK_TABLE (table), notebook, 0, 10, 1, 11);
gtk_widget_show(notebook);
for(i=0;i<5;i++){
label0[i]=gtk_label_new(title[i]);
frame[i]=gtk_frame_new(NULL);
gtk_container_set_border_width (GTK_CONTAINER (frame[i]), 10);
gtk_frame_set_shadow_type (GTK_FRAME (frame[i]),GTK_SHADOW_ETCHED_OUT);
gtk_widget_set_size_request(frame[i],450,450);
gtk_widget_show(frame[i]);
gtk_widget_show (label0[i]);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),frame[i],label0[i]);
table1[i]=gtk_table_new(12,11,TRUE);//创建表格 12 行*11 列
gtk_widget_show(table1[i]);//显示表格
gtk_container_add(GTK_CONTAINER(frame[i]),table1[i]);//将表格 tbale1 放入框架
}
cpu_bar=gtk_progress_bar_new();// 创建进度条
mem_bar=gtk_progress_bar_new();
swap_bar=gtk_progress_bar_new();
gtk_widget_show(cpu_bar);
gtk_widget_show(mem_bar);
gtk_widget_show(swap_bar);
time_label=gtk_label_new(" ");//显示系统时间
timer=gtk_timeout_add(1000,(GtkFunction)sys_time,data);//加一个定时器(timer),每隔1
秒调用一次(GtkFunction)sys_time 函数
gtk_table_attach_defaults(GTK_TABLE(table),time_label,10,12,1,2);//将时间标签装入 table
gtk_widget_show(time_label);
MenuBar=gtk_menu_bar_new();/*创建菜单栏*/
gtk_table_attach_defaults(GTK_TABLE(table),MenuBar,0,12,0,1);
MenuItemFile=CreateMenuItem(MenuBar,"文件");/*调用创建根菜单项函数*/
CreateMenuFile(MenuItemFile);/*调用创建根菜单项函数*/
MenuItemShutDown=CreateMenuItem(MenuBar,"关机选项");
CreateMenuShutDown(MenuItemShutDown);/*调用创建根菜单项函数*/
MenuItemHelp=CreateMenuItem(MenuBar,"帮助");
CreateMenuHelp(MenuItemHelp);/*调用创建根菜单项函数*/
gtk_widget_show(MenuBar);
status_bar0 = gtk_statusbar_new ();//创建状态栏显示 CPU 利用率
gtk_widget_show (status_bar0);
gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (status_bar0),TRUE);
process_label=gtk_label_new("");//创建显示进程数的标签
timer=gtk_timeout_add(1000,(GtkFunction)process_num,data);//加 一 个 定 时 器(timer), 每
隔1秒调用一次(GtkFunction)process_num 函数
gtk_widget_show(process_label);//显示标签
gtk_table_attach_defaults(GTK_TABLE(table),process_label,10,12,3,5);//在状态栏中显示进
程总数
cpu_rate_label=gtk_label_new(" ");//创建显示 cpu 占用率的标签
timer=gtk_timeout_add(1000,(GtkFunction)cpu_rate_ava,data);// 加 一 个 定 时 器
(timer),每隔1秒调用一次(GtkFunction)cpu_rate_ava 函数
gtk_widget_show(cpu_rate_label);//显示标签
gtk_table_attach_defaults(GTK_TABLE(table),cpu_rate_label,10,12,5,7);// 在 状 态 栏 中 显 示
cpu 占用率
mem_rate_label=gtk_label_new(" ");//创建显示内存占用率的标签
timer=gtk_timeout_add(1000,(GtkFunction)mem_rate_ava,data);//加一个定时器(timer),每
隔1秒调用一次(GtkFunction)mem_rate_ava 函数
gtk_widget_show(mem_rate_label);//显示标签
gtk_table_attach_defaults(GTK_TABLE(table),mem_rate_label,10,12,7,9);//在状态栏中显示
内存占用率
//显示 swap 使用率的标签
swap_rate_label=gtk_label_new("swap");
gtk_widget_show(swap_rate_label);
timer=gtk_timeout_add(1000,(GtkFunction)swap_rate_ava,data);
gtk_table_attach_defaults(GTK_TABLE(table),swap_rate_label,10,12,9,11);
//显示启动时间
start_time_label=gtk_label_new("www");
timer=gtk_timeout_add(1000,(GtkFunction)start_time,data);
gtk_widget_show(start_time_label);
gtk_table_attach_defaults(GTK_TABLE(table),start_time_label,0,5,11,12);
//显示系统运行时间
run_time_label=gtk_label_new("www");
timer=gtk_timeout_add(1000,(GtkFunction)start_time,data);
gtk_widget_show(run_time_label);
gtk_table_attach_defaults(GTK_TABLE(table),run_time_label,6,10,11,12);
timer=gtk_timeout_add(1000,(GtkFunction)get_cpu_rate,data);
cpu_button_clicked();//执行程序时默认显示各条信息
mem_button_clicked();
pro_button_clicked();
disk_button_clicked();
sys_button_clicked();
gtk_signal_connect(GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(delete_event)
,NULL);
gtk_main();
}
gint start_time(void){ //计算系统启动时间函数
int ut_fd,now_time,run_time,start_time,h,m,s;
char buf[30],*ch,buffer[20],tp[5],start[100]="系统启动时间:",buf0[100],buf1[100]="运行时
间:";
int f;
time_t timep;
struct tm *p;
gchar *delim=" ";
time(&timep);
p=localtime(&timep);
now_time=p->tm_hour*3600+p->tm_min*60+p->tm_sec;
ut_fd=open("/proc/uptime",O_RDONLY);
read(ut_fd,buf,sizeof (buf));
close(ut_fd);
ch=strtok(buf,delim);strtok(NULL,delim);strtok(NULL,delim);gtk_label_set_text(GTK_LABEL(r
un_time_label),ch);
run_time=atoi(ch);
start_time=now_time-run_time;
if(start_time<0){
start_time=24*3600+start_time;
}
h=start_time/3600;
m=(start_time-h*3600)/60;
s=start_time-h*3600-m*60;
sprintf(buffer,"%d",h);
strcat(buffer,":");
sprintf(tp,"%2d",m);
strcat(buffer,tp);
strcat(buffer,":");
sprintf(tp,"%2d",s);
strcat(buffer,tp);