操作系统课程设计报告 - 图文 下载本文

内容发布更新时间 : 2024/12/23 19:05:17星期一 下面是文章的全部内容请认真阅读。

3.5 题目四:应用/proc设计任务管理器

3.5.1 分模块设计

为了实现系统任务管理器System Mointer,首先将待实现的功能模块分为6个不同的部分,分别为:Process Info(查找进程信息)、CPU Ratio(CPU使用率)、MM Ratio(内存使用率)、System Info(系统基本信息)、New Process(创建新的进程)、Shut Down(关机)几个功能部分。 下面详细描述这几个模块: 1)Process Info 在主界面上单击 Process Info按钮后,会弹出一个新的窗口,界面如图所示。在文本框中输入所要查找的进程的pid,单击Find按钮,即弹出右边的窗口,显示进程信息(pid、进程名称、进程状态)。单击Kill按钮,即可杀死pid为当前文本框的数值的进程。 图3. 22 查找进程信息

图3. 21 SystemMonitor主界面

2)CPU使用率 单击主界面中的CPU Ratio按钮后,弹出窗口如右图所示。在窗口中显示CPU的使用的历史曲线。 3)内存使用率 单击主界面中的MM Ratio按钮后,弹出窗口如右图所示。在窗口中显示内存的使用的历史曲线。 4)系统基本信息 单击主界面中的System Info按钮后,弹出窗口如右图所示。在窗口中显示(1)主机名(2)系统启动的时间(3)系统到目前为止持续运行的时间(4)系统的版本号(5) cpu的型号和主频大小等信息。 图3. 25 查看系统的基本信息 16

图3. 23 查看CPU使用率 图3. 24 查看内存使用率 5)运行新的程序 单击主界面中的New Process按钮后,弹出窗口如右图所示。在文本框中输入程序的位置名称,单击OK,即可运行新的程序。 图3. 26 运行新的程序 6)关机 单击Shot Down按钮后,系统关机。 3.5.2 程序的实现

通过上述总结,对功能的需求有了一个全面的了解,为了实现上述功能,将需要做的工作分成以下几步:1)界面基本控件的使用 2)查找/proc信息的函数 3)利用/proc返回的信息计算CPU、MM使用率的函数、画图

在程序设计之前,先解决编译器和调试程序的问题。在下载了gtk后,使用code blocks即可进行程序的编译和调试,比使用gcc和gdb更为方便。 界面的实现:

通过模块的设计,总结出所需要的控件主要有窗口、按钮、显示文本框、输入文本框、列表。查找资料,找到实现这4个控件的方法。

以下程序在一个窗口中分别实现了按钮、显示文本框、输入文本框:

#include #include GtkWidget *text_view; GtkTextBuffer *buffer; GtkTextIter *Iter; void button_event(GtkWidget *widget,gpointer *data); int main(int argc,char *argv[ ]) { GtkWidget *window; GtkWidget *button; GtkWidget *box; 图3. 27 基本界面1 GtkWidget *label; gtk_init(&argc,&argv);//初始化GTK window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建新的窗口,用指针window指向该窗口 gtk_widget_set_size_request(window,200,150);//修改窗口大小 g_signal_connect(GTK_OBJECT(window),\当接到消息为destory时,调用函数毁掉该窗口 box=gtk_vbox_new(FALSE,0);//新建容器,用指针box指向容器 gtk_widget_show(box);//使容器可见 label = gtk_label_new(\新建标签显示”haha”,用指针label指向该标签 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 5); // 表示从前向后排列子控件 text_view=gtk_text_view_new();/*创建文本框构件*/ gtk_container_add(GTK_CONTAINER(window),box);//将容器加入窗口中 gtk_box_pack_start(GTK_BOX(box),text_view,FALSE,FALSE,0);// 表示从前向后排列子控件 buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));//获得当前文本框的内容 17

gtk_widget_show(text_view);//显示文本框 button=gtk_button_new_with_label(\创建按钮,使button指向该按钮 gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,5); // 表示从前向后排列子控件 gtk_signal_connect(GTK_OBJECT(button),\当接收到消息按钮被单击时,执行函数button_event gtk_widget_show_all(window);//显示窗口中所有控件 gtk_main(); } void button_event(GtkWidget *widget,gpointer *data)//发生单击按钮事件时使用回调函数 { gchar *text; GtkTextIter start,end; gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/ const GtkTextIter s=start,e=end; text=gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer),&s,&e,FALSE);/*获得文本框缓冲区文本*/ g_print(\} 通过实现上述这个小程序,掌握了实现各个模块基本控件的方法。基本上可以归纳为以下几步:1)定义GtkWidget型指针 2)调用函数新建控件3)控件内容、位置、类型的设置4)显示控件 列表的实现:

在查找进程的信息时使用了gtk的table控件,下面的例子是关于列表控件实现的。

#include void select_row_callback(GtkWidget *clist,gint row,gint column,GdkEventButton *event,gpointer data); int main(int argc,char *argv[ ]) { GtkWidget *window; GtkWidget *clist; gchar *text1[3]={\刘备\男\定义列表项数据*/ gchar *text2[3]={\关羽\男\gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(window),\图3. 28 基本界面2 NAL_FUNC(gtk_main_quit),NULL); gtk_widget_set_size_request(window,200,150); gtk_container_set_border_width(GTK_CONTAINER(window),10); clist=gtk_clist_new(3); gtk_clist_set_column_title(GTK_CLIST(clist),0,\姓名\gtk_clist_set_column_title(GTK_CLIST(clist),1,\姓别\gtk_clist_set_column_title(GTK_CLIST(clist),2,\年龄\gtk_clist_prepend(GTK_CLIST(clist),text1);/*将列表项数据添加到列表*/ gtk_clist_prepend(GTK_CLIST(clist),text2); gtk_signal_connect(GTK_OBJECT(clist),\捕捉select_row信号*/ gtk_clist_column_titles_show(GTK_CLIST(clist)); gtk_container_add(GTK_CONTAINER(window),clist); gtk_widget_show(clist); gtk_widget_show(window); gtk_main(); } void select_row_callback(GtkWidget *clist,gint row,gint column,GdkEventButton *event,gpointer data) /*设置select_row信号的回调函数*/ { gchar *text=NULL; 18

gtk_clist_get_text(GTK_CLIST(clist),row,column,&text); printf(\} 通过修改上述程序段,即可构建窗口显示所需要的进程相关的信息。 查找和处理/proc信息:

GetInfo 参数:path—待访问的文件的路径 info[]—作为缓冲,将从path读到的文件的第一行写入info 返回值:void 功能:获取信息并将信息返回 void GetInfo(char * path,char info []) { int fd=open(path,O_RDONLY); int i=0; char store[2000]; read(fd,store,sizeof(store)); close(fd); char *p=store; while(*p!='\\0'&&i<2000&&*p!='\\n')//从store读取第一行的内容到info { info[i]=*p; i++; p++; } info[i]='\\0'; } GetCpuMMInfo 参数:path—待访问的文件的路径,addinfo—待查找的信息的名称,info—返回的信息 返回值:void 功能:对于从/proc/cpuinfo和/proc/meminfo读取信息来说,并不是像其他文件中的读取那样只需要从第一行读取,而是需要根据特定的名称读取相应的信息的,所以,专门为读取这两个文件写了一个信息处理函数,基本功能相当于Getinfo void GetCpuMMInfo(char * path,char *addinfo,char info []) { int fd1=open(path,O_RDONLY); int i=0; char store1[2000]; read(fd1,store1,sizeof(store1)); close(fd1); char *p=store1; if((p=strstr(p,addinfo))==0) { return;//failed! printf(\ } while(*p!='\\0'&&i<2000&&*p!='\\n') { info[i]=*p; i++; p++; } info[i]='\\0'; } 19

GetTime 参数:info—用于返回当前时间的字符串 返回值:void int GetTime (char* info) { time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); //printf ( \ strcpy(info,asctime (timeinfo)); return 0; } DevInfo 参数:i—将获取信息编号,当需要获取某一信息时,Devinfo会用相应的参数调用函数使返回正确结果,m_info—返回所需要的信息 返回值:void 功能:统一处理访问/proc的需求,并分类,返回信息 void DevInfo(int i,char *m_info) { //char m_info[300]; switch(i) { case 0: GetInfo(\ break; case 1: GetInfo(\ break; case 2: GetInfo(\ break; case 3: GetInfo(\ break; case 4: GetInfo(\ break; case 5: GetCpuMMInfo(\ break; case 6: GetTime(m_info); break; case 7: GetInfo(\ break; case 8: GetCpuMMInfo(\ break; case 9: GetCpuMMInfo(\ break; } } 20