📄 monitor.c
字号:
/////本程序为LINUX下利用GTK编写的任务管理器
/////编译方法:
///// #gcc monitor.c –o monitor `pkg-config --cflags --libs gtk+-2.0
/////运行方法
///// ./monitor
#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <stdio.h>#include <signal.h>#include <fcntl.h>#include <dirent.h>#include <gdk/gdkkeysyms.h>#include <gtk/gtk.h>#include <gdk/gdk.h>#define DENSITY 100 //图形点密度#define PMAX 100 //最大进程数目enum{ NAME_COLUMN,//进程名列 PID_COLUMN,//进程PID列 STATUS_COLUMN,//进程状态列 CPU_COLUMN,//CPU信息列 MEMORY_COLUMN,//内存信息列 NP_COLUMNS};enum{ MOD_COLUMN, DEPEND_COLUMN, NM_COLUMNS};//控件声明GtkWidget *window;GtkWidget *main_vbox;GtkAccelGroup *accel_group;GtkItemFactory *item_factory;GtkWidget *menubar;GtkWidget *notebook;GtkWidget *label;GtkWidget *mem_label;GtkWidget *swap_label;GtkWidget *vbox;GtkWidget *cpu_draw_area;GtkWidget *mem_draw_area;GtkWidget *frame;GtkWidget *info_label;GString *info;GtkWidget *status_bar;GtkWidget *scrolled_window;GtkListStore *process_store;GtkWidget *ptree_view;GtkWidget *mtree_view;GtkCellRenderer *renderer;//用于显示tree view中的每个列标题GtkTreeViewColumn *column;//tree view控件列数GtkWidget *hbox; //hbox盒子GtkWidget *prefresh_button,*pdelete_button; //刷新进程按钮和结束进程按钮gdouble fuser = 0; //先前CPU使用信息gdouble ftotal = 0; //先前CPU使用总量 gdouble total = 0; //当前进程总数 gdouble pfuser[PMAX]; //最大进程数 gdouble rate = 0; //cpu 使用率gint cpu_graph[DENSITY]; //cpu 图形显示的密度gint mem_graph[DENSITY]; //内存 图形显示的密度GdkPixmap *cgraph = NULL; //pixmap指针,用于画cpu使用图形GdkPixmap *mgraph = NULL; //pixmap指针,用于画内存使用图形//函数声明 void destroy_window (GtkWidget *, gpointer);void sys_shutdown(GtkWidget *, gpointer);void sys_reboot (GtkWidget *, gpointer);void sys_halt (GtkWidget *, gpointer);void about_author (GtkWidget *, gpointer);gboolean handle_timeout (gpointer data);gboolean load_graph_refresh (gpointer data);gboolean get_cpu_rate (gpointer data);void create_sys_status_page (void);void create_process_page (void);void create_sys_info_page (void);void get_status_info (void);void get_process_info (GtkListStore *);void get_cpu_info (GString *);void get_os_info (GString *);void draw_cpu_load_graph (void);void draw_mem_load_graph (void);void prefresh_button_clicked (gpointer data);void pdelete_button_clicked (gpointer data);void mrefresh_button_clicked (gpointer data);void mdelete_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);void show_dialog (gchar *, gchar *);//定义菜单结构static GtkItemFactoryEntry menu_items[] = { {"/_File", NULL, NULL, 0, "<Branch>"}, {"/File/Quit", "<CTRL>Q", destroy_window, 0, "<Item>"}, {"/_Option", NULL, NULL, 0, "<Branch>"}, {"/Option/Shutdown", "<CTRL>U", sys_shutdown, 0 ,"<Item>"}, {"/Option/Reboot", "<CTRL>R", sys_reboot, 0 ,"<Item>"}, {"/Option/Halt", "<CTRL>H", sys_halt, 0 ,"<Item>"},};static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);//菜单项的数量int main (int argc, char **argv){ gtk_set_locale ();//设置环境变量,读取本地数据库 gtk_init (&argc, &argv); memset (cpu_graph, 50, sizeof (cpu_graph));//分配给cpu_graph结构50个大小为sizeof(cpu_graph)的空间 memset (mem_graph, 50, sizeof (mem_graph));//同上 memset (pfuser, 0 ,sizeof (pfuser)); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Linux System Moniter");//标题 gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);//默认窗口尺寸大小 gtk_window_set_resizable (GTK_WINDOW (window), FALSE);//窗口不可改变 g_signal_connect(G_OBJECT(window), "destroy", //将窗口关闭信息与destroy_window关联 G_CALLBACK(destroy_window), NULL); main_vbox =gtk_vbox_new (FALSE, 0);//从上到下的纵向组装盒 gtk_widget_show (main_vbox);//显示 gtk_container_add (GTK_CONTAINER (window), main_vbox);//将纵向盒加入窗口 accel_group = gtk_accel_group_new ();//创建GTK快捷键组 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);//创建菜单项 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL); gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);//加入快捷组 menubar = gtk_item_factory_get_widget (item_factory, "<main>");//获得菜单指针 gtk_widget_show (menubar);//显示 gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);//加入盒子 notebook = gtk_notebook_new ();//添加笔记本构件 gtk_widget_show (notebook); gtk_box_pack_start (GTK_BOX (main_vbox), notebook, FALSE, FALSE, 0); status_bar = gtk_statusbar_new ();//创建状态栏显示CPU利用率 gtk_widget_show (status_bar); gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (status_bar),TRUE); //创建可供用户拖动改变大小的“把柄” gtk_box_pack_start (GTK_BOX (main_vbox), status_bar, TRUE, FALSE, 0); gtk_timeout_add (3000, (GtkFunction)handle_timeout, NULL); //每3秒执行一次handle_timeout函数 gtk_timeout_add (1000, (GtkFunction)load_graph_refresh, NULL); //每1秒执行一次load_graph_refresh函数 gtk_timeout_add (1000, (GtkFunction)get_cpu_rate, NULL); //每1秒执行一次get_cpu_rate函数 create_process_page ();//创建记事本控件的几个页面 create_sys_status_page (); create_sys_info_page (); gtk_widget_show_all (window); gtk_main (); return 0;}void destroy_window (GtkWidget *widget, gpointer data)//退出本程序{ gtk_main_quit ();}void sys_shutdown (GtkWidget *widget, gpointer data)//关机{ system ("shutdown -r now");}void sys_reboot (GtkWidget *widget, gpointer data)//重启{ system ("reboot");}void sys_halt (GtkWidget *widget, gpointer data)//待机{ system ("halt");}gboolean handle_timeout (gpointer data)//定时进行的一系列操作{ gint page_num; page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));//获得笔记本构件当前活动页 switch (page_num) { case 0: break; case 1: gtk_list_store_clear (process_store);//清除treeview控件的存储的进程信息 get_process_info (process_store);//重新读取进程信息 break; default: break; } return TRUE;}gboolean load_graph_refresh (gpointer data)//更新cpu和内存使用率的图形显示{ draw_cpu_load_graph (); draw_mem_load_graph (); return TRUE;}gboolean get_cpu_rate ( gpointer data)//获得cpu使用率{ int fd,i; gchar buffer[256]; gchar *cpu_time[9]; gchar *tmp; gchar *delim = " "; gdouble cuser; gdouble ctotal; fd = open ("/proc/stat", O_RDONLY);//读取相关文件 read (fd, buffer, sizeof (buffer)); close (fd); tmp = strstr (buffer, "cpu0");//从开始到以"cpu0"为结束符的buffer的一部分字符到tmp tmp--; *tmp = '\0'; cpu_time[0] = strtok (buffer, delim);//通过字符串分割得到目的字符串 for (i = 1; i < 9 ; i++) { cpu_time[i] = strtok (NULL, delim); } cuser = atoi (cpu_time[1]);//将字符串转换为长整数 ctotal = (cuser + atoi (cpu_time[2]) + atoi (cpu_time[3]) + atoi (cpu_time[4])); total = ctotal - ftotal; rate = (cuser - fuser) / total; fuser = cuser; ftotal = ctotal; return TRUE;}void create_sys_status_page (void)//在笔记本中添加cpu和内存信息的页面{ vbox = gtk_vbox_new (FALSE, 0);//添加纵向盒子 gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (notebook), vbox);//加到笔记本容器中 frame = gtk_frame_new ("CPU");//添加用于显示CPU信息的边框构件 gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);//加到盒子中 cpu_draw_area = gtk_drawing_area_new ();//添加画图区构件用于图形化动态显示cpu利用情况 gtk_widget_show (cpu_draw_area); gtk_drawing_area_size (GTK_DRAWING_AREA (cpu_draw_area), 400, 100);//画图区大小设定 gtk_container_add (GTK_CONTAINER (frame), cpu_draw_area); g_signal_connect (cpu_draw_area, "expose_event", G_CALLBACK (cpu_expose_event), NULL);//暴光事件,用于刷新cpu画图区 g_signal_connect (cpu_draw_area, "configure_event", G_CALLBACK (cpu_configure_event), NULL); //窗口大小改变事件 frame = gtk_frame_new ("Memory");//添加用于显示内存信息的边框构件 gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 10); mem_draw_area = gtk_drawing_area_new (); gtk_widget_show (mem_draw_area); gtk_drawing_area_size (GTK_DRAWING_AREA (mem_draw_area), 400, 100); gtk_container_add (GTK_CONTAINER (frame), mem_draw_area); g_signal_connect (mem_draw_area, "expose_event", G_CALLBACK (mem_expose_event), NULL); g_signal_connect (mem_draw_area, "configure_event", G_CALLBACK (mem_configure_event), NULL); mem_label = gtk_label_new ("");//添加一个标签,显示内存的相关数据 gtk_widget_show (mem_label); gtk_box_pack_start (GTK_BOX (vbox), mem_label, FALSE, FALSE, 0); swap_label = gtk_label_new ("");//添加一个标签,显示页面交换使用情况 gtk_widget_show (swap_label); gtk_box_pack_start (GTK_BOX (vbox), swap_label, FALSE, FALSE, 10); label = gtk_label_new ("Status");//添加标签作为本页的标题 gtk_widget_show (label); gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), label);//增加到笔记本为该页标签}void create_process_page (void)//在笔记本中添加进程信息的页面{ int i; gchar *col_name[5] = { "NAME", "PID" , "STATUS", "CPU" , "MEMORY"}; vbox = gtk_vbox_new (FALSE, 0);//添加纵向盒子 gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (notebook), vbox);//加到笔记本容器里 scrolled_window = gtk_scrolled_window_new (NULL, NULL);//添加滚动窗口控件 gtk_widget_set_size_request (scrolled_window, 300, 300); gtk_widget_show (scrolled_window); gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); //进程信息 process_store = gtk_list_store_new (NP_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); ptree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (process_store)); //添加tree view控件,显示进程信息树 g_object_unref (G_OBJECT (process_store));//减少引用次数 gtk_widget_show (ptree_view); gtk_container_add (GTK_CONTAINER (scrolled_window), ptree_view);//将进程信息树加到滚动窗口中 for (i = 0; i < 5; i++) { renderer = gtk_cell_renderer_text_new ();//添加一个cell_renderer_text用于显示文字 column = gtk_tree_view_column_new_with_attributes (col_name[i], renderer, "text", i, NULL);//新建一列 gtk_tree_view_append_column (GTK_TREE_VIEW (ptree_view), column);//将该列加到树中 } get_process_info (process_store); //获取进程信息并存取显示到列表 hbox = gtk_hbox_new (FALSE, 0);//添加横排列盒子 gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);//增加到竖排列盒子中 prefresh_button = gtk_button_new ();//创建刷新进程信息按钮 gtk_widget_show (prefresh_button); gtk_widget_set_size_request (prefresh_button, 70, 30);//设置刷新按钮大小 gtk_button_set_label (GTK_BUTTON (prefresh_button), "refresh");//设置刷新按钮上显示的文字 g_signal_connect (G_OBJECT (prefresh_button),"clicked", G_CALLBACK(prefresh_button_clicked), NULL);//刷新按钮点击后执行prefresh_button_clicked gtk_box_pack_start (GTK_BOX (hbox), prefresh_button, TRUE, FALSE, 0);//增加该按钮到横排列盒子中 pdelete_button = gtk_button_new ();//创建杀死进程按钮 gtk_widget_show (pdelete_button); gtk_widget_set_size_request (pdelete_button, 70, 30); gtk_button_set_label (GTK_BUTTON (pdelete_button), "kill"); g_signal_connect (G_OBJECT (pdelete_button),"clicked", G_CALLBACK(pdelete_button_clicked), NULL);//该按钮点击后执行pdelete_button_clicked gtk_box_pack_start (GTK_BOX (hbox), pdelete_button, TRUE, FALSE, 0);//增加该按钮到横排列盒子中 label = gtk_label_new ("Processes");//进程信息的页标签 gtk_widget_show (label); gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0), label);//增加到笔记本为该页标签}void create_sys_info_page (void)//在笔记本中添加系统信息页
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -