版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、课程设计报告 课程名称:计算机操作系统 专业班级: 信安1302班 学 号: 姓 名: 指导教师: 报告日期: 2016.3.13 计算机科学与技术学院目 录一、 实验目的1二、 实验环境1三、 实验内容1四、 设计与实现24.1 实验一24.1.1 实验要求24.1.2 设计思路24.1.3 具体过程和结果34.1.3 源代码34.2实验二54.2.1 实验要求54.2.2 具体实现54.2.3 源代码74.3 实验三84.3.1 实验要求84.3.2 具体实现84.3.3 源程序104.4 实验四134.4.1 实验要求134.4.2 设计思路134.4.3程序效果显示174.4.4源代码
2、19五、 实验总结321、 实验目的(1) 掌握Linux操作系统的使用方法;(2) 了解Linux系统内核代码结构;(3) 掌握实例操作系统的实现方法。2、 实验环境本次课程设计采用的操作系统环境是Ubuntu系统,Ubuntu系统版本号为14.04,内核版本号为linux 3.18.27;采用的编程环境为gcc编译器和QtCreator。3、 实验内容实验一:掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。 (1) 编写一个C程序,其内容为实现文件拷贝的功能。 (2) 编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下
3、的图形库(GTK/Qt)。实验二:掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。另编写一个应用程序,使用新增加的系统调用。(1) 内核编译、生成,用新内核启动;(2) 新增系统调用实现:文件拷贝或P、V操作。实验三:掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。实现字符设备的驱动。实验四:使用GTK/QT实现系统监控器(1) 了解/proc文件的特点和使用方法;(2) 监控系统状态,显示系统中若干部件使用情况;(3) 用图形界面实现系统监控状态。4、 设计与实现4.1 实验一4.1.1 实验要求掌握Linux操作系统的使用方法,包括键盘命
4、令、系统调用;掌握在Linux下的编程环境。4.1.2 设计思路(1)要求编写一个C程序,其内容为实现文件拷贝的功能。在windows操作系统上实现的文件拷贝功能一般使用fopen、fread、fwrite三个来自标准C函数库的函数执行对文件的打开、读、写操作,而本次实验要求使用Linux系统的系统调用open、read、write实现上述三个操作。用到的主要头文件如下:stdio.h标准输入输出头文件string.h字符串处理相关头文件unistd.hLinux系统调用头文件,比如read、writefcntl.h包含open系统调用errno.h包含一些调试错误时用到的变量具体实现思路:打
5、开两个文件(分别是源文件和目标文件,可以是任意字符流形式存储的文件,包括文本文件、照片等),调用read函数读取源文件的内容,将read的返回值作为while循环的判断条件,当返回值大于0(即还未读取完毕源文件中的内容)时,调用write执行向目标文件写的操作,否则跳出循环,表示源文件已经被拷贝到目标文件,然后调用close关闭源文件和目标文件。(2) 编写一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。要求用到Linux下的图形库(GTK/Qt)。本次实验使用的图形库是跨平台的开发工具Qt。首先下载Qt的安装包并安装。Qt安装完之后,先新建一个Qt控制台应用MAIN作为主进程,用于
6、调用三个并发的子进程。在主进程的main函数中,使用fork创建三个子进程,若进程创建成功(即fork函数返回值等于0),则使用execv函数进入对应的子进程(window1、window2、window3)主进程程序编写完成后,再新建三个Qt Widgets Application,分别作为三个子进程,三个窗口显示了自己的进程号和父进程号。4.1.3 具体过程和结果(1) 代码完成后用保存为.c文件用gcc编译后./运行即可,实现的功能为复制文件1.txt为2.txt,如图4.1、4.2所示:图 4.1图 4.2(2) 主进程和三个子进程的程序全部编写完后,直接在Qt上编译运行。程序运行结果
7、如图4.3所示:图 4.34.1.3 源代码#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #define BUFFER_SIZE 1024 /缓冲区大小int main(int argc,char *argv) int from_fd,to_fd; int bytes_read
8、,bytes_write; char bufferBUFFER_SIZE; /设定一个缓冲区 char *ptr; if(argc!=3) /三个参数 fprintf(stderr,"Usage:%s fromfile tofilena",argv0);return(-1); /*打开源文件*/ if(from_fd=open(argv1,O_RDONLY)=-1) fprintf(stderr,"Open %s Error:%sn",argv1,strerror(errno); return(-1); /* 创建目的文件 */ if(to_fd=ope
9、n(argv2,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)=-1) fprintf(stderr,"Open %s Error:%sn",argv2,strerror(errno); return(-1); while(bytes_read=read(from_fd,buffer,BUFFER_SIZE) /* 出错*/ if(bytes_read=-1)&&(errno!=EINTR) break; else if(bytes_read>0) ptr=buffer; while(bytes_write=write(to_fd,
10、ptr,bytes_read) /* 出错*/ if(bytes_write=-1)&&(errno!=EINTR)break; /* 写完了所有读的字节 */else if(bytes_write=bytes_read) break; /* 只写了一部分,继续写 */ else if(bytes_write>0) ptr+=bytes_write; bytes_read-=bytes_write; /* 写的时候出错*/ if(bytes_write=-1)break; close(from_fd); close(to_fd); return(1);4.2实验二4.2.
11、1 实验要求掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编写一个应用程序,调用新增加的系统调用。4.2.2 具体实现(1) 系统调用的原理用户进程不能访问内核所占内存空间,也不能调用内核函数。进程调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置。在Intel CPU中,由中断INT 0x80实现。 (与DOS功能调用int0x21很相似)跳转到的内核位置叫做sysem_call。检查系统调用号,这个号码代表进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返
12、回到进程(如果这个进程时间用尽,就返回到其他进程)。(2) 编写新的系统调用程序新的系统调用程序实现的功能是:将一个文件中的内容拷贝到另一个文件中。这个系统调用的参数是两个char*型的字符指针SourceFile、GoalFile,分别表示源文件和目标文件的路径名。用户进程中的open、read、write、close函数此时对应内核函数 sys_open、 sys_read、 sys_write、 sys_close函数。循环拷贝的判断条件还是 sys_read的返回值,当其大于0的时候执行循环,否则表示源文件已拷贝到了目标文件。 mm_segment_t类型的变量fs的作用是在读写文件前
13、得到当前fs,避免使用的缓冲区超过了用户空间的地址范围而报错。(3) 编译内核下载并解压内核先到Linux官方网站下载内核linux-3.18.27.tar.xz。打开终端,使用sudo su获取root权限,然后使用cp linux-3.18.27.tar.xz /usr/src命令将linux-3.18.27tar.xz复制到文件夹/usr/src下,复制完毕之后将其解压,用到的命令为:xz -d linux-3.18.27.tar.xz和tar xvf linux-3.18.27.tar。修改内核新的内核解压完毕后,使用 cd /usr/src/linux-3.18.27命令进入目录 /
14、usr/src/linux-3.18.27。然后使用命令sudo gedit kernel/sys.c打开sys.c,将新的系统调用程序复制到该文件的文件末尾,保存退出,系统调用程序详细代码见源程序。系统调用号。在该文件中添加一行内容358 common mycall sys_mycall,其中系统调用号359不是固定的,只要该文件中没有出现的数字都可以使用。添加之后保存退出。使用命令sudo gedit include/asm-generic/syscalls.h打开syscalls.h,在“#endif /* _ASM_GENERIC_SYSCALLS_H */ 这一行的上面一行添加新的系
15、统调用程序的函数定义,即:#ifndef sys_mycallShrinkage int sys_mycall(char* sourceFile,char* destFile);#endif然后保存退出。#make menuconfig存盘退出,生成内核配置文件#make bzImage #make modules#make modules_install重启电脑选择高级选项选择新内核3.18.27进入,打开终端输入unmae -a,如图4.4表示,表示内核已编译成功:图 4.4(4) 编写系统调用测试程序需要用到的头文件是syscall.h、unistd.h、stdlib.h。在main函数
16、中直接调用头文件syscall.h中定义的函数syscall,该函数有三个参数,第一个参数是系统调用号(358),第二个参数是源文件(1.txt),第三个参数是目标文件。程序运行结果为:在2.c所在目录下新建了一个1.txt文件,并将main.c中的代码拷贝到了2.txt中,如图4.5所示:图 4.54.2.3 源代码(1) 系统调用程序asmlinkage int sys_mycall(char* SourceFile,char* GoalFile) int source=sys_open(SourceFile,O_RDONLY,0); int goal=sys_open(GoalFile,
17、O_WRONLY|O_CREAT|O_TRUNC,0600); char buff4096; mm_segment_t fs; fs = get_fs(); set_fs(get_ds(); int i; if(source>0 && goal>0) do i=sys_read(source,buff,4096); sys_write(goal,buff,i); while(i); else printk("Error!"); sys_close(source); sys_close(goal); set_fs(fs); return 10;(2
18、) 测试程序#include <syscall.h>#include <unistd.h>#include <stdlib.h>int main() syscall(359,"1.txt","2.text");return 0;4.3 实验三4.3.1 实验要求掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动程序,其功能可以简单。(实现字符设备的驱动)4.3.2 具体实现(1)Linux核心是一种monolithic类型的内核,即单一的大核心,另外一种形式是MicroKernel,核心的所有功能部件都被拆
19、成独立部分, 这些部分之间通过严格的通讯机制进行联系。Linux内核是一个整体结构,因此向内核添加任何东西.或者删除某些功能,都十分困难 。为了解决这个问题,引入了模块机制,从而可以动态的在内核中添加或者删除模块。模块一旦被插入内核,就和内核其他部分一样。Linux内核中的设备驱动程序是一组常驻内存的具有特权的共享库,是低级硬件处理例程。对用户程序而言,设备驱动程序隐藏了设备的具体细节, 对各种不同设备提供了一致的接口,一般来说是把设备映射为一个特殊的设备文 件,用户程序可以像对其它文件一样对此设备文件进行操作。Linux支持3种设备:字符设备、块设备和网络设备。设备由一个主设备号和一个次设备
20、号标识。主设备号唯一标识了设备类型, 即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释 ,一般用于识别在若干可能的硬件设备中,I/O请求所涉及到的那个设备。典型的Linux模块实现机制有如下几步:注册设备:在系统初启或者加载模块的时候,必须将设备登记到相应的设备数组,并返回主设备号。定义功能函数:对于每一个驱动函数来说,都有一些和此设备密切相关的功能函数。以最常用的块设备或者字符设备来说,都存在着诸如 open()、read()这一类的操作。当系统调用这些调用时,将自动的使用驱动函数中特定的模块来实现具体的操作。卸载设备:在不用这个设备时,可以将它卸载
21、,主要是从/proc 中取消这个设备的特殊文件。(2) 编写Makefile文件Makefile文件用于编译设备驱动程序,其内容如下:ifneq ($(KERNELRELEASE),) #kbuild syntax.#模块的文件组成mymodule-objs :=MyDeviceDriver.o #生成的模块文件名 obj-m := MyDeviceDriver.o elsePWD :=$(shell pwd)KVER :=$(shell uname -r)KDIR :=/lib/modules/$(KVER)/buildall:$(MAKE) -C $(KDIR) M=$(PWD)clean
22、:#rm -f *.cmd *.o *.mod *.korm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions#$(MAKE) -C $(KDIR) M=$(PWD) cleanendif(3) 编写设备功能函数编写设备驱动程序的主要工作就是编写子功能函数,并填充file_operations的各个域 。结构体file_operations的具体定义如下:struct file_operations struct module *owner;/拥有该结构的模块的指针,一般为THIS_MODULES
23、 loff_t (*llseek) (struct file *, loff_t, int);/用来修改文件当前的读写位置 ssize_t (*read) (struct file *, char _user *, size_t, loff_t *);/从设备中同步读取数据 ssize_t (*write) (struct file *, const char _user *, size_t, loff_t *);/向设备发送数据ssize_t (*aio_read) (struct kiocb *, co
24、nst struct iovec *, unsigned long, loff_t);/初始化一个异步的读取操作 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);/初始化一个异步的写入操作 int (*readdir) (struct file *, void *, filldir_t);/仅用于读取目录,对于设备文件,该字段为NULL unsigned int (
25、*poll) (struct file *, struct poll_table_struct *); /轮询函数,判断目前是否可以进行非阻塞的读写或写入 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); /执行设备I/O控制命令 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); /不使用BLK文件系统,将使用此种函数指针代替ioct
26、l long (*compat_ioctl) (struct file *, unsigned int, unsigned long); /在64位系统上,32位的ioctl调用将使用此函数指针代替 int (*mmap) (struct file *, struct vm_area_struct *); /用于请求将设备内存映射到进程地址空间 int (*open) (struct inode *, struct file *); /打开 i
27、nt (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); /关闭 int (*fsync) (struct file *, struct dentry *, int datasync); /刷新待处理的数据 int (*aio_fsync) (struct kiocb *, int datasync); /异步刷新待处理的数据
28、60; int (*fasync) (int, struct file *, int); /通知设备FASYNC标志发生变化 int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file
29、 *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
30、 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock *); ;(4) 设备驱动程序安装 make clean,清除make产生的残留 make,重新调用Makefile编译设备驱动程序 insmod -f MyDeviceDriver.ko,加载生成的 MyDeviceDr
31、iver.ko模块 cat /proc/devices,获取设备驱动程序的主设备号mknod /dev/MyDeviceDriver c 147 0,创建设备文件,147为主设备号,0为从设备号(5) 测试驱动程序此设备驱动程序实现的功能是将一个字符串中内容拷贝到另外一个字符串中。测试程序编写完成后,在终端输入gcc test.c -o test进行编译。测试结果如下:图 4.64.3.3 源程序(1) 设备驱动程序:#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#i
32、nclude <asm/uaccess.h>MODULE_LICENSE("GPL");#define MAJOR_NUM 147static ssize_t d_read(struct file *, char *, size_t, loff_t*);static ssize_t d_write(struct file *, const char *, size_t, loff_t*);static ssize_t d_open(struct inode *,struct file *);static ssize_t d_release(struct inod
33、e *,struct file *);struct file_operations d_fops= .read=d_read, .write=d_write, .open=d_open, .release=d_release,;static char var1024="Device test:"int counter=12;static int _init device_init(void) int result; result = register_chrdev(MAJOR_NUM, "device", &d_fops); if(result)
34、 printk("device register failure"); else printk("device register success"); return result;static void _exit device_exit(void) unregister_chrdev(MAJOR_NUM, "device"); printk("unloading the device.");static ssize_t d_read(struct file *filp, char *buf, size_t len
35、, loff_t *off) if(copy_to_user(buf,var,1024*sizeof(char) return - EFAULT; return sizeof(char);static ssize_t d_write(struct file *filp,const char *buf,size_t len,loff_t *off) if(copy_from_user(var+counter,buf,len*sizeof(char) return - EFAULT; counter+=len; return sizeof(char);static ssize_t d_open(s
36、truct inode *inode,struct file *file) printk(KERN_INFO "open it!n"); return 0;static ssize_t d_release(struct inode *inode,struct file *file) printk(KERN_INFO "close itn"); return 0; module_init(device_init);module_exit(device_exit);(2) 测试程序:#include <sys/types.h>#include &
37、lt;sys/stat.h>#include <stdio.h>#include <fcntl.h>#include <string.h>main() int fd; char buffer1024; int num; fd=open("/dev/3",O_RDWR,S_IRUSR|S_IWUSR); if(fd!=-1) read(fd,buffer,1024*sizeof(char); printf("The device is %sn",buffer); printf("Please input
38、the characters written to device:n"); fgets(buffer,1024,stdin); num=strlen(buffer)-1; write(fd,buffer,num*sizeof(char); read(fd,buffer,1024*sizeof(char); printf("The device is %sn",buffer); close(fd); else printf("Device open failuren"); 4.4 实验四4.4.1 实验要求了解/proc文件的特点和使用方法;监控
39、系统状态,显示系统中若干部件使用状态;用图形界面实现系统监控状态。4.4.2 设计思路(1)/proc文件系统的特点Linux的PROC文件系统是进程文件系统和内核文件系统的组成的复合体,是将内核数据对象化为文件形式进行存取的一种内存文件系统,是监控内核的一种用户接口。它拥有一些特殊的文件(纯文本),从中可以获取系统状态信息。(2)功能清单获取并显示主机名,与之相关的proc文件为/proc/sys/kernel/hostname;获取并显示系统启动的时间,与之相关的proc文件为/proc/uptime;显示系统到目前为止持续运行的时间,与之相关的proc文件为/proc/uptime;显示
40、系统的版本号,与之相关的proc文件为/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease; 显示CPU的型号和主频大小,与之相关的proc文件为/proc/cpuinfo;通过pid或者进程名查询一个进程,并显示该进程的详细信息,提供杀掉该进程的功能,与之相关的proc文件为/proc/(pid)/stat;显示系统所有进程的一些信息,包括pid、ppid、占用内存大小、优先级等,与之相关的proc文件为/proc/(pid)/stat, /proc/(pid)/statm;CPU使用率的图形化显示(2分钟内的历史记录曲线),与之相关的proc
41、文件为/proc/stat;内存和交换分区的使用率的图形化显示(2分钟内的历史曲线),与之有关的proc文件为/proc/meminfo;在状态栏显示当前时间,未使用到/proc中的文件;在状态栏显示当前CPU使用率,与之相关的proc文件为/proc/stat;在状态栏显示当前内存使用情况,与之相关的proc文件为/proc/meminfo;用新线程运行一个其他程序,未使用到/proc中的文件;关机功能,未使用到/proc中的文件;(3)功能实现获取并显示主机名用file.open函数打开/proc/sys/kernel/hostname文件,然后以文件指针为输入流,从其中读出一行字符包含主
42、机名,然后直接输出在label上,即主机名。获取并显示系统启动的时间从文件/proc/uptime中获取系统启动到现在的运行时间(单位是s),直接获取当前时间addSecs(-runtime),然后用timetostring以时间日期的格式显示出来。显示系统到目前为止持续运行的时间打开/proc/uptime文件,然后以文件指针为输入流读出一行数据输出在label上即可。显示系统的版本号从/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease中读取系统类型(比如linux)和系统内核版本号,处理方法和获取系统运行时间的方法一样。得到系统类型和系统内
43、核版本号之后,调用QString类的方法arg将两个字符串连接起来,再输出显示即可。显示CPU的型号和主频大小打开/proc/cpuinfo文件后读取任一CPU型号和频率即可。通过pid或者进程名查询一个进程,并显示该进程的详细信息,提供杀掉该进程的功能在获取所有进程信息的时候,获取到的所有信息已经被存储在一个全局结构体数组变量中了,所以查询的时候,先获取输入lineEdit中的文本(QString类型),然后将文本与全局结构体数组变量的每一个数组元素的name成员和pid成员作比较,若相等,说明待查询的进程存在,将该进程的详细信息输出即可。杀死进程前先要获取将要被杀死进程的名称或者pid,而
44、且该进程必须存在于/proc目录下,即先查询一次待杀死的进程,处理方法如上所述。Linux系统提供了kill、pkill等杀死进程的命令,pkill通过pid杀死进程,kill通过进程名称杀死进程。通过将lineEdit中的内容和kill或pkill组成终端命令,然后调用system函数执行这些命令即可杀死相应的进程。显示系统所有进程的一些信息,包括pid、ppid、占用内存大小、优先级等系统的进程众多,本次实验我采用的是Linux中对目录进行操作的函数opendir(),readdir()。实现思路为:声明一个DIR类型的指针dir,用opendir函数打开/proc目录,返回值赋值给dir
45、,然后将dir作为函数readdir的参数,readdir函数返回值复制给dirent结构体指针ptr。ptr指向的结构体包含d_name char数组成员,即文件或者目录名,将d_name数组的0号元素分别和字符1、9比较,若处于这两者之间,则表明该文件或者目录是进程目录,以该目录名为参数调用获取进程详细信息的函数read_proc。在read_proc函数中,使用格式化输出函数sprintf将参数目录名c_pid对应目录下的文件stat的路径输出到char数组filename中,再调用C+的类ifstream,声明一个ifstream类性的变量meminfo,用filename初始化mem
46、info,然后用析取器(>>)从meminfo中输入数据到结构体数组procInfo的每个元素的成员变量中,析取器(>>)会自动忽略空字符。所需要的进程信息并不是连续存放在stat文件中的,中间包含有其他不需要显示的进程信息,解决方法是定义一个string类型的变量temp,根据stat文件中的信息存放顺序,将所有不需要的进程信息全部输入到temp中。此外还要注意一个问题,进程名称带有括号“()”,所以需要将括号去掉,解决方法是使用string类的方法substr,该函数的参数有两个,一个是想截取的字符串首字符在原字符串中的位置,第二个参数是想截取的字符串末尾字符后面一
47、个字符,在这里就是“)”。处理完毕之后,所需要的关于进程c_pid的详细信息都存储在全局结构体数组procInfo的元素中了。循环采用上述思路,直到所有进程目录都被处理完毕,所有的进程信息就都存储在了全局结构体数组procInfo中,然后用定时器触发定时更新全局结构体数组procInfo中的内容。CPU使用率的图形化显示使用qcustomplot插件画图即可,数据用一个120大小的数组存储即可内存和交换分区的使用率的图形化显示同CPU使用率的图像相似用数组存好数据后调用即可。在状态栏显示当前时间调用QDateTime的方法currentDateTime获取当前时间time,time是一个QDa
48、teTime类型的变量,然后调用QDateTime的方法toString把time转化成格式为yyyy-MM-dd hh:mm:ss dddd的QString字符串,再在主窗口的状态栏显示输出即可。在状态栏显示当前CPU使用率CPU的使用率是指CPU的使用时间和CPU总时间的比值。因为/proc/stat文件中的所有值都是从系统启动开始累计到当前时刻,所以计算CPU使用率时需要取两个采样点,利用两个点的差值计算CPU使用率,此次实验采样方法是每隔1秒采样一次。CPU使用率的计算公式为cpuRate=100.0-(idle2-idle1)*100.0/(total2-total1)。定义一个全局
49、结构体CPU_USE,具体定义如下:typedef struct CPU_USE char name16;/cpu unsigned int user; unsigned int nice; unsigned int system; unsigned int idle; unsigned int iowait;unsigned int irq; unsigned int softirq;cpu_use;CPU总时间的值等于结构体CPU_USE中7个unsigned int类型的成员值之和。计算之前,调用get_cpu_use_stat函数获取一个CPU状态,sleep一秒后再调用该函数获取第二
50、个CPU状态,然后用上述CPU使用率计算公式计算即可。在状态栏显示当前内存使用情况内存使用率是指已使用的内存和总内存的比值。内存使用率的计算公式为:memRate=(total (free+buffers+cached)*100.0/total。定义一个全局结构体MEM_USE,具体定义如下:typedef struct MEM_USE unsigned long total; unsigned long free; unsigned long buffers; unsigned long cached;mem_use;该结构体中的成员的值都来自文件/proc/meminfo, 声明一个ifs
51、tream类性的变量meminfo,用/proc/meminfo初始化meminfo, 然后用析取器(>>)从meminfo中输入数据到结构体mem_use 的成员变量中,析取器(>>)会自动忽略空字符。所需要的内存数据信息并不是连续存放在/proc/meminfo文件中的,中间包含有其他不需要的内存数据信息,解决方法是定义一个string类型的变量str,根据/proc/meminfo文件中的信息存放顺序,将所有不需要的内存数据信息全部输入到str中。得到内存使用的数据信息之后,使用上述内存使用率计算公式计算即可。用新线程运行一个其他程序在主窗口中添加一个lineEd
52、it控件,获取该控件中输入的程序名称,然后调用QProcess类的start方法运行该程序。关机功能由于关机功能需要输入密码获取root权限,所以需要想方法在点击关机按钮后输入密码。定义一个QString类型的变量passWord,调用类QInputDialog的方法getText,会弹出一个对话框提示输入密码,该方法的返回值即为密码,将返回值赋值给passWord变量;当对话框的OK按钮被点击时,用QString("echo %1 | sudo -S shutdown -h now").arg(passWord)初始化QString类型的变量sudo,再把sudo转换成c
53、har*类型,然后调用system函数执行关机命令。(4)界面设计实验四用QT写界面,较为简便,将主界面分为四页,第一页是系统信息,第二页是进程信息,第三页提供杀进程和创建进程,第四页是历史图像,至于CPU使用率和内存使用率用一个Bar显示。4.4.3程序效果显示4.4.4源代码Mainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include<QLabel>#include<QPushButton>class QTabWidget;namespace Ui c
54、lass MainWindow;class MainWindow : public QMainWindow Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); MainWindow();private: Ui:MainWindow *ui; private: void HostName(); void BootTime(); void OSType(); void add_point(float cpuRate); void UpdateCPULine(); void CPUInfo();private slots: void N
55、owTime(); void CPURate(); void MemRate(); void run_time(); void ProcessInfo(); void QueryProcess(); void KillProcess(); void CreateProcess(); void on_reboot_clicked();#endif / MAINWINDOW_HCPU.H#ifndef CPU_H#define CPU_H#include <stdio.h>#include <stdlib.h>#include <QString>#include <QFile>#include <QTextStream>typedef struct CPU_USE char name16; unsigned
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022年福建省中考物理模拟试题分类:力学填空题
- 2019-2021年河北省中考物理试题分类汇编-实验题
- 中南大学《重力场与重力勘探》2022-2023学年第一学期期末试卷
- 中南大学《土力学》2022-2023学年第一学期期末试卷
- 中南大学《生产运作管理》2022-2023学年第一学期期末试卷
- 中南大学《基础工程》2021-2022学年第一学期期末试卷
- 中南大学《构造地质学》2023-2024学年期末试卷
- 中南大学《儿科护理学》2022-2023学年第一学期期末试卷
- 中南大学《材料结构分析(一)》2021-2022学年第一学期期末试卷
- 中国劳动关系学院《应急管理学》2021-2022学年第一学期期末试卷
- 保山2024年云南保山市市直事业单位遴选管理人员和专业技术人员30人笔试历年典型考题及考点附答案解析
- 【超星尔雅学习通】伦理学概论(北京师范大学)网课章节答案
- 能源调度中心方案
- 《建筑工程制图》题库
- 工程联系单表格样本
- 滑坡泥石流-高中地理省公开课金奖全国赛课一等奖微课获奖
- 三年级上册数学除法竖式计算300道带答案
- 《hadoop基础》课件-第二章 Hadoop介绍
- 铜矿的热法冶炼与电法冶炼
- 客户分析方案
- 股东合作协议(经典版本)
评论
0/150
提交评论