一.实验目的
1.掌握Linux操作系统的使用方法;
2.了解Linux系统内核代码结构;
3.掌握实例操作系统的实现方法。
二. 实验环境
ubuntu8.04(内核Linux-2.6.24-23)
三. 实验内容
1.编写一个C程序,使用Linux下的图形库,分窗口显示三个并发进程的运行。
2.采用模块方法,添加一个新的设备驱动程序;要求添加字符设备的驱动,编写一个 程序测试所写的驱动。
3.了解/proc文件的特点和使用方法,监控系统状态,显示系统中若干部件的使用情 况,用图形界面显示系统监控状态。
四. 实验具体过程
1. 编写一个C程序,使用Linux下的图形库,分窗口显示三个并发进程的运行
a.程序说明
首先是主程序通过fork函数创建新进程,然后通过调用execv打开新文件以
到并发执行三个程序的目的. 子程序则使用了GTK编程,窗口1显示一个滚动条,窗口2显示输出文本,窗口3既显示滚动条,又显示文本输出。
b.程序源码
子程序1:
//编译: gcc -o progress_bar progress_bar.c `pkg-config --cflags --libs gtk+-2.0`
#include
#include
GtkWidget *window;
GtkWidget *table;
GtkWidget *button;
GtkWidget *progress_bar;
// 更新进度条,这样就能够看到进度条的移动
gint progress_timeout( gpointer data ){
gdouble value;
int v;
char text[20]="0%";
//使用在调整对象中设置的取值范围计算进度条的值
value=gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR (progress_bar))+0.01;
if (value>1.0)
value=0.0;
v=(int)(value*100);
strcpy(text," ");
sprintf(text,"%d",v);
strcat(text,"% ");
// 设置进度条的新值
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar),value);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),text);
//这是一个timeout函数,返回 TRUE,这样它就能够继续被调用
//如果想要结束,可以在进度条到100%时,return 0;这样回调函数就会结束
return TRUE;
}
int main(int argc,char *argv[]){
int timer;
gpointer data;
gtk_init(&argc,&argv);//在任何构件生成之前完成
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗口
gtk_window_set_title(GTK_WINDOW(window),"窗口1");//设置窗口标题
gtk_widget_set_usize(window, 200, 200);//设置窗口大小
gtk_container_set_border_width(GTK_CONTAINER(window),5);//设置窗口边框宽度
gtk_widget_show(window);//显示窗口
gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
table=gtk_table_new(3,5,TRUE);//创建表格3行*5列
gtk_widget_show(table);//显示表格
gtk_container_add(GTK_CONTAINER(window),table);//将table1装进窗口
/* 创建进度条 */
progress_bar=gtk_progress_bar_new();
gtk_table_attach_defaults(GTK_TABLE(table),progress_bar,0,5,0,1);//进度条装进表格
gtk_widget_show(progress_bar);
/* 加一个定时器(timer),以更新进度条的值 */
timer=gtk_timeout_add(100,progress_timeout,data);
/* 添加一个按钮,用来退出应用程序 */
button = gtk_button_new_with_label ("close");
gtk_table_attach_defaults(GTK_TABLE(table),button,0,5,2,3);//进度条装进表格
gtk_widget_show (button);
gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
gtk_main ();
return 0;
}
子程序2:
//编译: gcc -o window_text window_text.c `pkg-config --cflags --libs gtk+-2.0`
#define GTK_ENABLE_BROKEN
#include
#include
GtkWidget *window;
GtkWidget *table;
GtkWidget *label;
GtkWidget *text;
int i=0;
gint text_timeout( gpointer data ){
char buf[20];
char temp[10];
sprintf(temp,"%d",i);
strcpy(buf,"show text ");
strcat(buf,temp);
strcat(buf,"/n");
//将buf内容插入到文本构件中
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf,-1);
i++;
//这是一个timeout函数,返回 TRUE,这样它就能够继续被调用
//如果想要结束,可以在进度条到100%时,return 0;这样回调函数就会结束
return TRUE;
}
int main(int argc,char *argv[]){
GtkWidget *vscrollbar;
int timer;
gpointer data;
gtk_init(&argc,&argv);//在任何构件生成之前完成
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗口
gtk_window_set_title(GTK_WINDOW(window),"窗口2");//设置窗口标题
gtk_widget_set_usize(window, 200, 200);//设置窗口大小
gtk_container_set_border_width(GTK_CONTAINER(window),5);//设置窗口边框宽度
gtk_widget_show(window);//显示窗口
gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
table=gtk_table_new(11,10,TRUE);//创建表格11行*10列
gtk_container_add(GTK_CONTAINER(window),table);//将table1装进窗口
gtk_widget_show(table);//显示表格
label=gtk_label_new("ShowText");
gtk_table_attach_defaults(GTK_TABLE(table),label,0,10,0,1);
gtk_widget_show (label);
text=gtk_text_new(NULL,NULL);//创建文本构件
gtk_widget_show(text);//显示文本构件
//将文本构件装进表格
gtk_table_attach_defaults(GTK_TABLE(table),text,0,9,1,11);
//创建滚动条并设置其与文本同步
vscrollbar=gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
gtk_widget_show (vscrollbar);//显示垂直滚动条
gtk_table_attach_defaults (GTK_TABLE (table), vscrollbar,9,10,1,11);//将滚动条装进表格
timer=gtk_timeout_add(1000,text_timeout,data);//调用回调函数,每隔1秒输出一行文本
gtk_main ();
return 0;
}
子程序3:
//编译: gcc -o text_bar text_bar.c `pkg-config --cflags --libs gtk+-2.0`
#define GTK_ENABLE_BROKEN
#include
#include
GtkWidget *window;
GtkWidget *table;
GtkWidget *button;
GtkWidget *progress_bar;
GtkWidget *label;
GtkWidget *text;
int i=0;
gint text_timeout( gpointer data ){
char buf[20];
char temp[10];
sprintf(temp,"%d",i);
strcpy(buf,"show text_bar ");
strcat(buf,temp);
strcat(buf,"/n");
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf,-1);
i++;
//这是一个timeout函数,返回 TRUE,这样它就能够继续被调用
//如果想要结束,可以在进度条到100%时,return 0;这样回调函数就会结束
return TRUE;
}
// 更新进度条,这样就能够看到进度条的移动
gint progress_timeout( gpointer data ){
gdouble value;
int v;
char text[20]="0%";
//使用在调整对象中设置的取值范围计算进度条的值
value=gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress_bar))+0.01;
if (value>1.0)
value=0.0;
v=(int)(value*100);
strcpy(text," ");
sprintf(text,"%d",v);
strcat(text,"% ");
// 设置进度条的新值
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar),value);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),text);
//这是一个timeout函数,返回 TRUE,这样它就能够继续被调用
//如果想要结束,可以在进度条到100%时,return 0;这样回调函数就会结束
return TRUE;
}
int main(int argc,char *argv[]){
GtkWidget *vscrollbar;
int timer;
gpointer data;
gtk_init(&argc,&argv);//在任何构件生成之前完成
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗口
gtk_window_set_title(GTK_WINDOW(window),"窗口3");//设置窗口标题
gtk_widget_set_usize(window, 400, 400);//设置窗口大小
gtk_container_set_border_width(GTK_CONTAINER(window),5);//设置窗口边框宽度
gtk_widget_show(window);//显示窗口
gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
table=gtk_table_new(10,8,TRUE);//创建表格10行*8列
gtk_widget_show(table);//显示表格
gtk_container_add(GTK_CONTAINER(window),table);//将table1装进窗口
label=gtk_label_new("ShowText");
gtk_table_attach_defaults(GTK_TABLE(table),label,0,8,1,2);
gtk_widget_show (label);
text=gtk_text_new(NULL,NULL);//创建文本构件
gtk_widget_show(text);//显示文本构件
//将文本构件装进表格
gtk_table_attach_defaults(GTK_TABLE(table),text,0,7,2,9);
//创建滚动条并设置其与文本同步
vscrollbar=gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
gtk_widget_show (vscrollbar);//显示垂直滚动条
gtk_table_attach_defaults (GTK_TABLE (table), vscrollbar,7,8,2,9);//将滚动条装进表格
timer=gtk_timeout_add(1000,text_timeout,data);
/* 创建进度条 */
progress_bar=gtk_progress_bar_new();
gtk_table_attach_defaults(GTK_TABLE(table),progress_bar,0,8,0,1);//进度条装进表格
gtk_widget_show(progress_bar);
/* 加一个定时器(timer),以更新进度条的值 */
timer=gtk_timeout_add(100,progress_timeout,data);
/* 添加一个按钮,用来退出应用程序 */
button = gtk_button_new_with_label ("close");
gtk_table_attach_defaults(GTK_TABLE(table),button,3,5,9,10);//进度条装进表格
gtk_widget_show (button);
gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
gtk_main ();
return 0;
}
主程序:
#include
#include
#include
#include
#include
int semid;
char *finish;
int p1,p2;
int main (void){
if((p1=fork())==0){//创建新进程
execv("./progress_bar",NULL);
}
else{
if((p2=fork())==0){
execv("./window_text",NULL);
}
else{
execv("./text_bar",NULL);
}
}
return 0;
}
程序运行结果:
2.采用模块方法,添加一个新的设备驱动程序 ;要求添加字符设备的驱动,编写一个 程序测试所写的驱动。
a.程序说明
对于实现字符设备的驱动,首先要挂载字符设备,然后加载设备的驱动程序,然后再调用测试程序进行测试.首先编译自己写的驱动,编译成功后再用“insmod mydev.ko”来装载驱动,接着创建设备节点,用户进程通过/dev/mydev这个路径就可以访问到这个全局变量虚拟设备了,使用“mknod 路径(如/dev/mydev) c 主设备号 次设备号”来实现,卸载设备使用“rmmod 设备名“通过cat /proc/devices来查看所有挂载的设备,所有这些完成后便可以开始测试了,编写测试程序test.c包含读设备和写设备.
注意:在编译设备时,如果采用命令行编译,很有可能会提示找不到头文件,这个或许是因为你的linux系统没有内核头文件的源码包,可以采用编写makefile文件来编译设备,如果还不行,可以去下载一个内核源码包,重新编译内核,或者干脆还一个linux系统。
b.程序源代码
字符设备源代码:
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
int mydev_major = 0;
char *buffer=" ";
ssize_t mydev_write (struct file *filp, const char __user *buf, size_t count,loff_t *pos){
int ret;
ret=copy_from_user(buffer,buf,count);
return 1;
}
//buf是用户进程空间的一个地址.但是在mydev_read被调用时,系统进入核心态.
//所以不能使用buf这个地址,必须用copy_to_user,这是kernel提供的一个函数,用于向用户传送数据.
ssize_t mydev_read(struct file *filp, char __user *buf,size_t count, loff_t *pos){
int ret;
ret=copy_to_user(buf,buffer,count);
return 1;
}
struct file_operations mydev_fops ={ //系统调用和驱动程序关联起来
.read = mydev_read,
.write = mydev_write,
.owner = THIS_MODULE
};
int mydev_init(void){
if((mydev_major=register_chrdev (0, "mydev", &mydev_fops))>=0){
printk("register success!/n");
return 1;
}
else{
printk("register failed!/n");
return 0;
}
}
void mydev_cleanup(void){
unregister_chrdev (mydev_major, "mydev");
}
module_init(mydev_init);
module_exit(mydev_cleanup);
makefile文件:
ifneq ($(KERNELRELEASE),)
obj-m := mydev.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
install:
sudo insmod mydev.ko
unstall:
sudo rmmod mydev
clean:
rm -rf *.o *.ko .*.cmd *.mod.c .tmp_versions
测试程序源代码:
#include "fcntl.h"
#include "unistd.h"
#include "stdio.h"
#include "sys/types.h"
#include "sys/stat.h"
#include
int main()
{
char buf[32];
int fd;
printf("please input:");
scanf("%s",buf);
fd=open("/dev/mydev",O_RDWR); //要在根用户下运行
if(write(fd,buf,32)<0){
printf("error in write/n");
}
if(read(fd,buf,32)<0)
{
printf("error in read/n");
return 0;
}
else
{
printf("The content readed from mydev is : %s/n",buf);
return 1;
}
}
程序编译及运行如下:(都要在根用户下进行)
先在终端 输入:make
接着 :make install(或者insmod mydev.ko)
然后输入 :cat /proc/devices 查看字符设备是否已经挂载,如下
可见分配的主设备号为253
然后输入 : mknod /dev/mydev c 253 0 创建设备节点
然后测试程序:gcc -o test test.c
./test
结果如下:please input:dsakfdja
The content readed from mydev is : dsakfdja
最后卸载设备:make unstall(或者rmmod mydev)
删除设备节点:rm /dev/mydev
通过:cat /proc/devices 查看设备是否已经卸载
3.了解/proc文件的特点和使用方法,监控系统状态,显示系统中若干部件的使用情 况,用图形界面显示系统监控状态。
主要参考书目:<
a.程序说明:
1。首先编写GTK界面:
创建窗口;
然后创建表格,将表格添加进窗口,创建一个菜单条放在表格的第一行,再创建5个按钮放在第二行,靠左对齐,在第二行的最右添加一个标签,用于显示系统时间;
创建一个状态栏放在表格最末行;
在第三行至倒数第二行的表格中创建一个框架;
在框架中又创建一个表格:在表格中创建一个文本构件(当按钮点击时产生事件,在文本构件中实时显示对应按钮的信息。
2。读取/proc中的信息:
从/proc/stat读取cpu各状态的时间,进而算出cpu利用率;
从/proc/meminfo读取内存总量和可用内存,算出内存利用率;
从/proc这个目录下读取数字文件夹的数量,即是进程总数;
从/proc/cpuinfo读取cpu的信息;
从/proc/meminfo读取内存信息;
从/proc/进程号/status读取进程名,/proc/进程号/statm读取进程占用内存大 小,进而显示出进程相关信息;
从/proc/partitions读取硬盘信息;
从/proc/sys/kernel/hostname读取主机名;
从/proc/version读取内核版本;
为了格式化显示这些读取的信息,使用了strtok字符串分割函数,sprintf函数可以从某种规则中读取出自己需要的字符串,sscanf函数则是连接两个字符串最好的操作参数。
3。事件处理及实时显示
事件处理用gtk_signal_connect,实时显示则用gtk_timeout_add调用回调函数来达到每隔一段时间更新显示。
b.程序源代码
//编译时如下: gcc -o proctemppd proctemppd.c `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
struct Process{
char name[25];
char pro_id[10];
char cpu_take[10];
char mem_take[10];
}pro[200];
char *title[5]={"CPU","Mem","Proc","Disk","Sys"};
char *title1[5]={"cpu version&run state","memory state","process state","disk information","system time&kernel version"};
GtkWidget *text;
GtkWidget *table;
GtkWidget *table1;//定义表格
GtkWidget *frame;//定义框架
GtkWidget *button[5],*label1,*cpu_rate_label,*process_label,*mem_rate_label,*time_label;//定义标签
gint length;
int mem_flag,pro_flag;//定义两个标志变量,用来判断是否结束回调函数
GtkWidget *CreateMenuItem(GtkWidget *,char *);
GtkWidget *CreateMenuFile(GtkWidget *);
GtkWidget *CreateMenuShutDown(GtkWidget *);
GtkWidget *CreateMenuHelp(GtkWidget *);
gint cpu_rate_ava(void);
gint mem_rate(void);
gint process_num(void);
gint mem_timeout(void);
gint pro_timeout(void);
gint sys_time(void);
void cpu_button_clicked(GtkWidget *,gpointer *);
void mem_button_clicked(GtkWidget *,gpointer *);
void pro_button_clicked(GtkWidget *,gpointer *);
void disk_button_clicked(GtkWidget *,gpointer *);
void sys_button_clicked(GtkWidget *,gpointer *);
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 shutdown(GtkWidget *window,gpointer data){//回调函数,关机
system("halt");
}
void aboutgtk(GtkWidget *window,gpointer data){//输出有关gtk的信息
GtkWidget *dialog,*label,*dtable,*text;
char *buf="Library to build graphical user interfaces (GUIs)/noriginally for X Window. Designed to be small, /nefficient, flexible. Coded in C, in very object-oriented/n ";
dialog=gtk_dialog_new();
gtk_widget_set_usize(dialog, 200, 200);
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("AboutGtk");
gtk_table_attach_defaults(GTK_TABLE(dtable),label,0,10,0,1);
gtk_widget_show (label);
text=gtk_text_new(NULL,NULL);//创建文本构件
gtk_widget_show(text);//显示文本构件
//将文本构件装进表格
gtk_table_attach_defaults(GTK_TABLE(dtable),text,0,10,1,11);
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf,-1);
gtk_widget_show(dialog);
}
int main(int argc,char *argv[]){
GtkWidget *window;//定义窗口
gint i;
GtkWidget *vscrollbar,*hscrollbar;//定义滚动条
GtkWidget *notebook;//定义笔记本
GtkWidget *status_bar;//定义状态栏
GtkWidget *MenuBar;/*定义菜单条*/
GtkWidget *MenuItemFile,*MenuItemShutDown,*MenuItemHelp;
gpointer data;
gint sign;
gtk_init(&argc,&argv);//在任何构件生成之前完成
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗口
gtk_window_set_title(GTK_WINDOW(window),"Source Manager");//设置窗口标题
gtk_widget_set_usize(window, 480, 500);//设置窗口大小
gtk_container_set_border_width(GTK_CONTAINER(window),5);//设置窗口边框宽度
gtk_widget_show(window);//显示窗口
table=gtk_table_new(12,10,TRUE);//创建表格11行*10列
gtk_widget_show(table);//显示表格
gtk_container_add(GTK_CONTAINER(window),table);//将table1装进窗口
for(i=0;i<5;i++){
button[i]=gtk_button_new_with_label(title[i]);
gtk_table_attach_defaults(GTK_TABLE(table),button[i],i,i+1,1,2);
gtk_widget_show(button[i]);
}
frame=gtk_frame_new(NULL);//创建框架
gtk_container_set_border_width(GTK_CONTAINER(frame),0);//设置框架边框宽度
//设置框架的风格
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
gtk_table_attach_defaults(GTK_TABLE(table),frame,0,10,2,11);
gtk_widget_show(frame);//显示框架
table1=gtk_table_new(12,11,TRUE);//创建表格12行*11列
gtk_widget_show(table1);//显示表格
gtk_container_add(GTK_CONTAINER(frame),table1);//将表格放入框架
text=gtk_text_new(NULL,NULL);//创建文本框构件
//buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));//获得文本框缓冲区
gtk_widget_show(text);//显示文本构件
//将文本构件装进表格
gtk_table_attach_defaults(GTK_TABLE(table1),text,0,10,1,12);
//创建滚动条并设置其与文本同步
vscrollbar=gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
gtk_widget_show (vscrollbar);//显示垂直滚动条
gtk_table_attach_defaults (GTK_TABLE (table1), vscrollbar,10,11,1,12);//将滚动条装进表格
label1=gtk_label_new("进程名/t/t进程号/t/t占用内存");
gtk_table_attach_defaults(GTK_TABLE(table1),label1,0,11,0,1);
time_label=gtk_label_new(" ");//显示系统时间
sign=gtk_timeout_add(100,(GtkFunction)sys_time,data);
gtk_table_attach_defaults(GTK_TABLE(table),time_label,8,10,1,2);
gtk_widget_show(time_label);
//以下为点击按钮的时间响应函数
gtk_signal_connect(GTK_OBJECT(button[0]),"clicked",GTK_SIGNAL_FUNC(cpu_button_clicked),NULL);
gtk_signal_connect(GTK_OBJECT(button[1]),"clicked",GTK_SIGNAL_FUNC(mem_button_clicked),NULL);
gtk_signal_connect(GTK_OBJECT(button[2]),"clicked",GTK_SIGNAL_FUNC(pro_button_clicked),NULL);
gtk_signal_connect(GTK_OBJECT(button[3]),"clicked",GTK_SIGNAL_FUNC(disk_button_clicked),NULL);
gtk_signal_connect(GTK_OBJECT(button[4]),"clicked",GTK_SIGNAL_FUNC(sys_button_clicked),NULL);
MenuBar=gtk_menu_bar_new();/*创建菜单条*/
gtk_table_attach_defaults(GTK_TABLE(table),MenuBar,0,10,0,1);
MenuItemFile=CreateMenuItem(MenuBar,"File");/*调用创建菜单项函数*/
CreateMenuFile(MenuItemFile);/*调用创建子菜单函数*/
MenuItemShutDown=CreateMenuItem(MenuBar,"ShutDown");
CreateMenuShutDown(MenuItemShutDown);/*调用创建子菜单函数*/
MenuItemHelp=CreateMenuItem(MenuBar,"Help");
CreateMenuHelp(MenuItemHelp);/*调用创建子菜单函数*/
gtk_widget_show(MenuBar);
status_bar = gtk_statusbar_new (); /*创建状态栏*/
gtk_table_attach_defaults(GTK_TABLE(table),status_bar,0,10,11,12);//将状态栏装进表格
gtk_widget_show (status_bar); /*显示状态栏*/
process_label=gtk_label_new("");//创建显示进程数的标签
sign=gtk_timeout_add(100,(GtkFunction)process_num,data);
gtk_widget_show(process_label);//显示标签
gtk_table_attach_defaults(GTK_TABLE(table),process_label,0,2,11,12);//在状态栏中显示进程总数
cpu_rate_label=gtk_label_new(" ");//创建显示cpu占用率的标签
sign=gtk_timeout_add(100,(GtkFunction)cpu_rate_ava,data);
gtk_widget_show(cpu_rate_label);//显示标签
gtk_table_attach_defaults(GTK_TABLE(table),cpu_rate_label,3,5,11,12);//在状态栏中显示cpu占用率
//printf("/n%.2f",cpu_rate);
mem_rate_label=gtk_label_new(" ");//创建显示内存占用率的标签
sign=gtk_timeout_add(100,(GtkFunction)mem_rate,data);
gtk_widget_show(mem_rate_label);//显示标签
gtk_table_attach_defaults(GTK_TABLE(table),mem_rate_label,6,10,11,12);//在状态栏中显示内存占用率
GtkWidget *wi;
cpu_button_clicked(wi,data);//执行程序时默认显示cpu信息
gtk_signal_connect(GTK_OBJECT(window),"delete_event",GTK_SIGNAL_FUNC(delete_event),NULL);
gtk_main();
}
GtkWidget *CreateMenuItem(GtkWidget *MenuBar,char *test){
GtkWidget *MenuItem;
MenuItem=gtk_menu_item_new_with_label(test);/*创建菜单项*/
gtk_menu_shell_append(GTK_MENU_SHELL(MenuBar),MenuItem);/*把菜单项加入菜单条*/
gtk_widget_show(MenuItem);
return MenuItem;
}
GtkWidget *CreateMenuFile(GtkWidget *MenuItem){
GtkWidget *Menu;/*定义子菜单*/
GtkWidget *Exit;
Menu=gtk_menu_new();/*创建子菜单*/
Exit=CreateMenuItem(Menu,"Exit");/*调用创建菜单项函数*/
gtk_signal_connect(GTK_OBJECT(Exit),"activate",GTK_SIGNAL_FUNC(delete_event),NULL);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(MenuItem),Menu);/*把父菜单项于子菜单联系起来*/
gtk_widget_show(Menu);
}
GtkWidget *CreateMenuShutDown(GtkWidget *MenuItem){
GtkWidget *Menu;/*定义子菜单*/
GtkWidget *Restart,*ShutDown;
Menu=gtk_menu_new();/*创建子菜单*/
ShutDown=CreateMenuItem(Menu,"ShutDown");/*调用创建菜单项函数*/
Restart=CreateMenuItem(Menu,"Restart");
gtk_signal_connect(GTK_OBJECT(Restart),"activate",GTK_SIGNAL_FUNC(restart),NULL);
gtk_signal_connect(GTK_OBJECT(ShutDown),"activate",GTK_SIGNAL_FUNC(shutdown),NULL);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(MenuItem),Menu);/*把父菜单项于子菜单联系起来*/
gtk_widget_show(Menu);
}
GtkWidget *CreateMenuHelp(GtkWidget *MenuItem){
GtkWidget *Menu;/*定义子菜单*/
GtkWidget *AboutGtk;
Menu=gtk_menu_new();/*创建子菜单*/
AboutGtk=CreateMenuItem(Menu,"AboutGtk");/*调用创建菜单项函数*/
gtk_signal_connect(GTK_OBJECT(AboutGtk),"activate",GTK_SIGNAL_FUNC(aboutgtk),NULL);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(MenuItem),Menu);/*把父菜单项于子菜单联系起来*/
gtk_widget_show(Menu);
}
gint sys_time(void){//显示系统时间
time_t timep;
struct tm *p;
char buf[20],temp[5];
time(&timep);
p=localtime(&timep); /*取得当地时间*/
sprintf(buf,"%d",p->tm_hour);
sprintf(temp,"%d",p->tm_min);
strcat(buf,":");
strcat(buf,temp);
sprintf(temp,"%d",p->tm_sec);
strcat(buf,":");
strcat(buf,temp);
gtk_label_set_text(GTK_LABEL(time_label),buf);
return 1;
}
//实时显示cpu占用率
gint cpu_rate_ava(void){//计算从系统启动到现在cpu的利用率
char buffer[1024*5];
char *match;
FILE *fp;
size_t bytes;
char show[5];
float cpu_rate;
char text_cpu[14]="CPU : ";
//GtkWidget *cpu_rate_label;
int user,nice,system,idle;
fp = fopen("/proc/stat","r");
if (fp == 0){
printf("open /proc/stat file error/n");
return 0;
}
bytes = fread(buffer, 1, sizeof(buffer),fp);
fclose(fp);
if (bytes == 0 || bytes == sizeof(buffer)){
printf("readBytes NULL OR large than buffer /n");
return 0;
}
buffer[bytes] = '/0';
match = strstr (buffer, "cpu");
if (match == NULL){
printf("match error/n");
return 0;
}
sscanf (match ,"cpu %d %d %d %d", &user, &nice, &system, &idle);
cpu_rate=100*(user+nice+system)/(float)(user+nice+system+idle);
//printf( "user :%d nice: %d sys: %d idle %d cpu_rate: %.2f%%/n",user, nice, system, idle,cpu_rate);
sprintf(show,"%.2f",cpu_rate);
strcat(text_cpu,show);
strcat(text_cpu,"%");
gtk_label_set_text(GTK_LABEL(cpu_rate_label),text_cpu);
return 1;
}
//实时显示内存占用率
gint mem_rate(void){//计算内存使用率
int mem_fd;
int MemFree,MemTotal,MemUsed,i=0,j=0;
char buf[1000],buf1[1000]=" ",buf2[100]=" ",buf3[100]=" ",buf4[100]=" ",string[20];
char *p;
char Mem[100]=" ";
mem_fd=open("/proc/meminfo",O_RDONLY);
read(mem_fd,buf,1000);
close(mem_fd);
strcat(buf1,strtok(buf,"/n"));
strcat(buf2,buf1);
for(i=0;i<100&&buf2[i]!='/0';i++)
if(buf2[i]>='0'&&buf2[i]<='9')buf3[j++]=buf2[i];
buf3[j]='/0';
MemTotal=atoi(buf3);
strcat(buf1,strtok(NULL,"/n"));
strcpy(buf2,buf1);
j=0;
for(;i<100&&buf2[i]!='/0';i++)
if(buf2[i]>='0'&&buf2[i]<='9')buf4[j++]=buf2[i];
buf4[j]='/0';
MemFree=atoi(buf4);
MemUsed=MemTotal-MemFree;
//printf("MemUsed:%dkB/MemTotal:%dkB/n",MemUsed,MemTotal);
MemTotal=MemTotal/1024;
MemUsed=MemUsed/1024;
strcpy(Mem,"Memory:");
sprintf(string,"%d",MemUsed);//将整数转换成字符串
strcat(Mem,string);
strcat(Mem,"M/");
sprintf(string,"%d",MemTotal);
strcat(Mem,string);
strcat(Mem,"M");
gtk_label_set_text(GTK_LABEL(mem_rate_label),Mem);
return 1;
}
//实时显示进程总数
gint process_num(void){
DIR * dir;
struct dirent * ptr;
char show[5];
int total=0;
char text_value[100]="进程总数:";
//统计进程总数
dir =opendir("/proc");
while((ptr = readdir(dir))!=NULL){
if(select_name(ptr->d_name)){
total++;
}
}
sprintf(show,"%3d",total);
strcat(text_value,show);
closedir(dir);
gtk_label_set_text(GTK_LABEL(process_label),text_value);
}
//显示cpu信息的按钮事件
void cpu_button_clicked(GtkWidget *widget,gpointer *data){
int cpu_fd,i;
char buf[1000],buf1[1000]=" ";
char *p;
pro_flag=0;
mem_flag=0;
cpu_fd=open("/proc/cpuinfo",O_RDONLY);
read(cpu_fd,buf,1000);
close(cpu_fd);
strcat(buf1,strtok(buf,"/n"));
while(p=strtok(NULL,"/n")){
strcat(buf1,"/n ");
strcat(buf1,p);
}
gtk_frame_set_label(GTK_FRAME(frame),"cpu version&run state");
gtk_widget_hide(label1);
length=gtk_text_get_length(GTK_TEXT(text));//获取当前文本的字符数
gtk_text_backward_delete(GTK_TEXT(text),length);//从当前插入点向前删除length个字符
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf1,-1);//从当前插入点开始插入字符串,-1表示将整个字符串插入
}
//显示内存信息的回调函数
gint mem_timeout(void){
int mem_fd;
char buf[1000],buf1[1000]=" ";
char *p;
gint sign;
gpointer gdata;
if(!mem_flag)return 0;//退出回调函数
mem_fd=open("/proc/meminfo",O_RDONLY);
read(mem_fd,buf,1000);
close(mem_fd);
strcat(buf1,strtok(buf,"/n"));
while(p=strtok(NULL,"/n")){
strcat(buf1,"/n ");
strcat(buf1,p);
}
gtk_frame_set_label(GTK_FRAME(frame),"memory state");
gtk_widget_hide(label1);
length=gtk_text_get_length(GTK_TEXT(text));
gtk_text_backward_delete(GTK_TEXT(text),length);
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf1,600);
return 1;
}
//点击内存按钮后的事件
void mem_button_clicked(GtkWidget *widget,gpointer *data){
gint sign;
gpointer gdata;
mem_flag=1;
pro_flag=0;
mem_timeout();
//调用回调函数
sign=gtk_timeout_add(1000,(GtkFunction)mem_timeout,gdata);
}
//显示进程信息的回调函数
gint pro_timeout(void){
DIR * dir;
struct dirent * ptr;
int fdfrom;
int total=0;
int bytesread;
char buffer[80];
char text_value[100]="进程总数 : ";
char show[5];
char buff[100]=" ";
int i=0,j;
char path_statm[30];
char path_status[30];
if(!pro_flag)return 0;
dir =opendir("/proc");
while((ptr = readdir(dir))!=NULL){
if(select_name(ptr->d_name)){
strcpy(pro[i].pro_id,ptr->d_name);
i++;total++;
}
}
//printf("%d/n",total);
sprintf(show,"%3d",total);
strcat(text_value,show);
closedir(dir);
gtk_frame_set_label(GTK_FRAME(frame),"process state");
length=gtk_text_get_length(GTK_TEXT(text));
gtk_text_backward_delete(GTK_TEXT(text),length);
for(i=0;i
strcpy(path_statm,"/proc/");
strcpy(path_status,"/proc/");
strcat (path_statm,pro[i].pro_id);
strcat (path_statm,"/statm");
strcat (path_status,pro[i].pro_id);
strcat (path_status,"/status");
fdfrom=open(path_status,O_RDONLY);//为了读取进程名
bytesread=read(fdfrom,buffer,30);
if(bytesread<=0)
printf("read error!/n");
strtok(buffer,": ");
strcpy(pro[i].name,strtok(NULL,"/n"));
close(fdfrom);
fdfrom=open(path_statm,O_RDONLY);//为了读取进程占用内存大小
bytesread=read(fdfrom,buffer,30);
if(bytesread<=0)
printf("read error!/n");
strcat(pro[i].mem_take,strtok(buffer," "));
strcat(pro[i].mem_take,"kb");
close(fdfrom);
strcat(buff,pro[i].name);
for(j=strlen(pro[i].name);j<27;j++)//调整格式
strcat(buff," ");
strcat(buff,pro[i].pro_id);
for(j=strlen(pro[i].pro_id);j<16;j++)
strcat(buff," ");
strcat(buff,pro[i].mem_take);
strcat(buff,"/n");
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buff,-1);
strcpy(pro[i].mem_take," ");
strcpy(buff," ");
}
gtk_widget_show(label1);
return 1;
}
//显示进程信息的按钮事件
void pro_button_clicked(GtkWidget *widget,gpointer *data){
gpointer gdata;
pro_flag=1;
mem_flag=0;
pro_timeout();
//调用进程信息的回调函数
gtk_timeout_add(10000,(GtkFunction)pro_timeout,gdata);
}
//显示硬盘信息的按钮事件
void disk_button_clicked(GtkWidget *widget,gpointer *data){
int disk_fd,i;
char buf[1000],buf1[1000]=" ";
char *p;
pro_flag=0;
mem_flag=0;
disk_fd=open("/proc/partitions",O_RDONLY);
read(disk_fd,buf,1000);
close(disk_fd);
strcat(buf1,strtok(buf,"/n"));
while(p=strtok(NULL,"/n")){
strcat(buf1,"/n/n ");
strcat(buf1,p);
}
gtk_frame_set_label(GTK_FRAME(frame),"disk information");
gtk_widget_hide(label1);
length=gtk_text_get_length(GTK_TEXT(text));
gtk_text_backward_delete(GTK_TEXT(text),length);
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf1,-1);
}
//显示内核信息的按钮事件
void sys_button_clicked(GtkWidget *widget,gpointer *data){
int sys_fd,i,hour,second,minute;
char buf[2000]=" ",buf1[1000];
char *p;
char showm[20];
int time_run;
time_t timep;
char *sys_info[]={"/proc/sys/kernel/hostname","/proc/version"};
pro_flag=0;
mem_flag=0;
gtk_frame_set_label(GTK_FRAME(frame),"kernel version");
gtk_widget_hide(label1);
strcat(buf,"/n/n/n/nhostname : ");
sys_fd=open(sys_info[0],O_RDONLY);
read(sys_fd,buf1,1000);
close(sys_fd);
strcat(buf,strtok(buf1,"/n"));
strcat(buf,"/n");
strcat(buf,"/n/nkernel vertion : ");
sys_fd=open(sys_info[1],O_RDONLY);
read(sys_fd,buf1,1000);
close(sys_fd);
strcat(buf,strtok(buf1,"("));
strcat(buf,"/n");
length=gtk_text_get_length(GTK_TEXT(text));
gtk_text_backward_delete(GTK_TEXT(text),length);
gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,buf,-1);
}
c.程序运行结果:
1。整体框架
2。状态栏
3
3。内存实时显示:
4。进程实时显示:
5。显示硬盘信息
6。显示内核信息
7。点击help显示有关gtk的信息