操作系统课设

上传人:时间****91 文档编号:120897921 上传时间:2022-07-18 格式:DOC 页数:67 大小:716KB
返回 下载 相关 举报
操作系统课设_第1页
第1页 / 共67页
操作系统课设_第2页
第2页 / 共67页
操作系统课设_第3页
第3页 / 共67页
点击查看更多>>
资源描述
课 程 设 计 报 告课程名称: 计算机操作系统专业班级: 学 号: 姓 名: 指引教师: 报告日期: 计算机科学与技术学院目 录1实验目的22实验环境23实验内容23.1实验一23.2实验二23.3实验三23.4实验四(选做)33.5实验五(选做)34设计与实现34.1实验一34.2实验二104.3实验三144.4实验四205心得体会431 实验目的掌握Linux操作系统的使用措施;理解Linux系统内核代码构造;掌握实例操作系统的实现措施;2 实验环境本次课程设计采用的操作系统环境是windows8、Ubuntu双系统,Ubuntu系统版本号为14.04,内核版本号为linux 3.13.0;采用的编程环境为CodeBlocks IDE和QtCreator。3 实验内容3.1 实验一掌握Linux操作系统的使用措施,涉及键盘命令、系统调用;掌握在Linux下的编程环境。(1)编写一种C程序,其内容为实现文献拷贝的功能。(2)编写一种C程序,其内容为分窗口同步显示三个并发进程的运营成果。规定用到Linux下的图形库(GTK/Qt)。3.2 实验二掌握系统调用的实现过程,通过编译内核措施,增长一种新的系统调用,另编写一种应用程序,调用新增长的系统调用。实现的功能是:文献拷贝。3.3 实验三掌握增长设备驱动程序的措施。通过模块措施,增长一种新的设备驱动程序,其功能可以简朴。(实现字符设备的驱动)3.4 实验四(选做)理解和掌握/proc文献系统的特点和使用措施(1)理解/proc文献的特点和使用措施;(2)监控系统状态,显示系统中若干部件使用状态;(3)用图形界面实现系统监控状态;3.5 实验五(选做)设计并实现一种模拟的文献系统。多顾客的多级目录的文献系统设计。多顾客、多级目录、login(顾客登录)、系统初始化(建文献卷,提供登录模块)、文献的创立、文献的打开、文献的读写、文献关闭、删除文献、创立目录(建立子目录)、变化目前目录、列出文献目录、退出。4 设计与实现4.1 实验一4.1.1 实验规定掌握Linux操作系统的使用措施,涉及键盘命令、系统调用;掌握在Linux下的编程环境。4.1.2 具体实现本实验内容是用CodeBlocks IDE实现的,该软件整合了函数库和编译器,因此使用起来非常以便。(1)编写一种C程序,其内容为实现文献拷贝的功能。在windows操作系统上实现的文献拷贝功能一般使用fopen、fread、fwrite三个来自原则C函数库的函数执行对文献的打开、读、写操作,而本次实验规定使用Linux系统的系统调用open、read、write实现上述三个操作。用到的重要头文献如下:stdio.h原则输入输出头文献string.h字符串解决有关头文献unistd.hLinux系统调用头文献,例如read、writefcntl.h涉及open系统调用errno.h涉及某些调试错误时用到的变量具体实现思路:打开两个文献(分别是源文献和目的文献,可以是任意字符流形式存储的文献,涉及文本文献、照片等),调用read函数读取源文献的内容,将read的返回值作为while循环的判断条件,当返回值不小于0(即尚未读取完毕源文献中的内容)时,调用write执行向目的文献写的操作,否则跳出循环,表达源文献已经被拷贝到目的文献,然后调用close关闭源文献和目的文献。代码编写完毕后,在CodeBlocks上编译运营即可。程序运营之前,桌面上只有“教程.docx”,运营之后,桌面上新建了“教程副本.docx”,并且“教程.docx”中的内容被复制到了“教程副本.docx”,程序运营成果如下所示:具体代码见Error! Reference source not found.。(2)编写一种C程序,其内容为分窗口同步显示三个并发进程的运营成果。规定用到Linux下的图形库(GTK/Qt)。本次实验使用的图形库是跨平台的开发工具Qt。一方面下载Qt的安装包并安装。Qt安装完之后,先新建一种Qt控制台应用MAIN作为主进程,用于调用三个并发的子进程。在主进程的main函数中,使用fork创立三个子进程,若进程创立成功(即fork函数返回值等于0),则使用execv函数进入相应的子进程(get、copy、put)。主进程程序编写完毕后,再新建三个Qt Widgets Application,分别作为三个子进程get、copy、put(所实现的功能并不是拷贝)。由于三个子进程窗口显示的内容形式一模同样,因此以子进程get为例。get进程的窗口显示了一下四个内容:目前时间、子进程名称、子进程的pid和父进程MAIN的pid。用Qt的对象QDateTime获取系统目前时间,然后将时间转换成一种字符串写在一种QLabel类的实例中,然后将该实例添加至窗口;直接把目迈进程名称写在一种标签上然后添加至窗口;使用getpid和getppid函数分别获取目迈进程号和父进程号,然后调用sprintf把进程号转换成字符串类型之后写在标签上并添加至窗口即可。主进程和三个子进程的程序所有编写完后,直接在Qt上编译运营。程序运营成果如下所示:具体代码见Error! Reference source not found.。4.1.3 源代码(1) 文献拷贝源代码#include #include #include #include #include #include #include #define SIZE 10 /每次读取的字符数目char * srcFile=/home/ilbear/桌面/教程.docx;char *goalFile=/home/ilbear/桌面/教程副本.docx;int main(int argc, const char *argv) int src, goal; int read_len; char buffSIZE; src=open(srcFile,O_RDONLY); if(src0) printf(Fail to open %sn.,srcFile); exit(1); goal=open(goalFile,O_WRONLY|O_CREAT,0666); if(goal0) write(goal,buff,read_len); close(src); close(goal); return 0;(2) 三个并发进程#主进程MAIN#include #include #include #include #include #include int main(int argc, char *argv) QCoreApplication a(argc, argv); pid_t p1,p2,p3; if(p1=fork()=0) execv(/home/ilbear/桌面/build-get-Desktop_Qt_5_4_1_GCC_64bit-Debug/get,NULL); else if(p2=fork()=0) execv(/home/ilbear/桌面/build-copy-Desktop_Qt_5_4_1_GCC_64bit-Debug/copy,NULL); else if( p3=fork()=0) execv(/home/ilbear/桌面/build-put-Desktop_Qt_5_4_1_GCC_64bit-Debug/put,NULL); waitpid(p1,NULL,0); waitpid(p2,NULL,0); waitpid(p3,NULL,0); return a.exec();#子进程getmainwindow.cpp#include mainwindow.h#include ui_mainwindow.h#include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory1(share1) ui-setupUi(this); setWindowTitle(get); setWindowFlags(Qt:Dialog); move(0,0); resize(500,500); char str128,f_id128; sprintf(str,%d,getpid(); sprintf(f_id,%d,getppid(); ui-textBrowser-setText(get); ui-textBrowser_2-setText(str); ui-textBrowser_3-setText(f_id); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(), this, SLOT(timerUpDate(); timer-start(1);MainWindow:MainWindow() delete ui;void MainWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str);#子进程copymainwindow.cpp#include mainwindow.h#include ui_mainwindow.h#include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory1(share1),sharememory2(share2) char str128,f_id128; ui-setupUi(this); setWindowTitle(copy); setWindowFlags(Qt:Dialog); move(500,500); resize(500,500); sprintf(str,%d,getpid(); sprintf(f_id,%d,getppid(); ui-textBrowser-setText(copy); ui-textBrowser_2-setText(str); ui-textBrowser_3-setText(f_id); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(), this, SLOT(timerUpDate(); timer-start(1);MainWindow:MainWindow() delete ui;void MainWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str);#子进程putmainwindow.cpp#include mainwindow.h#include ui_mainwindow.h#include #include #include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui:MainWindow),sharememory2(share2) char str128,f_id128; ui-setupUi(this); setWindowTitle(put); setWindowFlags(Qt:Dialog); move(1000,0); resize(500,500); sprintf(str,%d,getpid(); sprintf(f_id,%d,getppid(); ui-textBrowser-setText(put); ui-textBrowser_2-setText(str); ui-textBrowser_3-setText(f_id); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(), this, SLOT(timerUpDate(); timer-start(1);MainWindow:MainWindow() delete ui;void MainWindow:timerUpDate() QDateTime time = QDateTime:currentDateTime(); QString str = time.toString(yyyy-MM-dd hh:mm:ss dddd); ui-labelCurDate-setText(str);4.2 实验二4.2.1 实验规定掌握系统调用的实现过程,通过编译内核措施,增长一种新的系统调用,另编写一种应用程序,调用新增长的系统调用。4.2.2 具体实现(1) 系统调用的原理顾客进程不能访问内核所占内存空间,也不能调用内核函数。进程调用一种特殊的指令,这个指令会跳到一种事先定义的内核中的一种位置。在Intel CPU中,由中断INT 0x80实现。 (与DOS功能调用int0x21很相似)跳转到的内核位置叫做sysem_call。检查系统调用号,这个号码代表进程祈求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做某些系统检查,最后返回到进程(如果这个进程时间用尽,就返回到其她进程)。(2) 编写新的系统调用程序新的系统调用程序实现的功能是:将一种文献中的内容拷贝到另一种文献中。这个系统调用的参数是两个char*型的字符指针SourceFile、GoalFile,分别表达源文献和目的文献的途径名。顾客进程中的open、read、write、close函数此时相应内核函数 sys_open、 sys_read、 sys_write、 sys_close函数。循环拷贝的判断条件还是 sys_read的返回值,当其不小于0的时候执行循环,否则表达源文献已拷贝到了目的文献。 mm_segment_t类型的变量fs的作用是在读写文献前得到目前fs,避免使用的缓冲区超过了顾客空间的地址范畴而报错。具体代码见Error! Reference source not found.。(3) 编译内核下载并解压内核先到Linux官方网站。打开终端,使用sudo su获取root权限,然后使用cp linux-3.14.36.tar.xz /usr/src命令将linux-3.14.36.tar.xz复制到文献夹/usr/src下,复制完毕之后将其解压,用到的命令为:xz -d linux-3.14.36.tar.xz和tar xvf linux-3.14.36.tar。修改内核新的内核解压完毕后,使用 cd /usr/src/linux-3.14.36命令进入目录 /usr/src/linux-3.14.36。然后使用命令sudo gedit kernel/sys.c打开sys.c,将新的系统调用程序复制到该文献的文献末尾,保存退出,系统调用程序具体代码见4.2.3。使用命令sudo gedit arch/x86/syscalls/syscall_64.tbl 打开 syscall_64.tbl添加系统调用号。在该文献中添加一行内容317 common mycall sys_mycall,其中系统调用号317不是固定的,只要该文献中没有浮现的数字都可以使用。添加之后保存退出。使用命令sudo gedit include/asm-generic/syscalls.h打开syscalls.h,在“#endif /* _ASM_GENERIC_SYSCALLS_H */ 这一行的上面一行添加新的系统调用程序的函数定义,即:#ifndef sys_mycallasmlinkage int sys_mycall(char* sourceFile,char* destFile);#endif然后保存退出。编译内核在编译内核之前先要安装ncurses库,使用命令sudo apt-get install libncurses5-dev安装。安装完毕后,进入 /usr/src/linux-3.14.36目录下,新建一种脚本文献mysyscall.sh,通过命令gedit mysyscall.sh打开该脚本文献进行编辑。将如下内容添加到脚本中:#!/bin/bashmake mrproper make menuconfig make depmake clean make bzImage j4make modules j4make modules_install j4make install j4mkinitramfs -o /boot/initrd.img-3.14.34 update-grub reboot保存退出,然后修改脚本文献的权限,使其可以对内核文献进行操作,修改权限的命令为chmod 777 mysyscall.sh。权限修改成功后,在终端中运营该脚本文献./mysyscall.sh,内核开始编译,期间会浮现配备linux过程,直接先save,然后OK,再exit即可,继续等待编译结束。编译完毕后,电脑会自动重启,重启选择进入Ubuntu高档选项,在选项列表中选择新内核linux-3.14.36进入,打开终端输入uname -a查看系统版本号,执行状况如下所示:阐明已经成功进入新的内核linux-3.14.36中。(4) 编写系统调用测试程序需要用到的头文献是syscall.h、unistd.h、stdlib.h。在main函数中直接调用头文献syscall.h中定义的函数syscall,该函数有三个参数,第一种参数是系统调用号(317),第二个参数是源文献(main.c,即测试程序的源代码文献),第三个参数是目的文献(yyk.text)。程序运营成果为:在main.c所在目录下新建了一种yyk.text文献,并将main.c中的代码拷贝到了yyk.text中。具体代码见Error! Reference source not found.。4.2.3 源代码(1) 系统调用程序asmlinkage int sys_mycall(char* SourceFile,char* GoalFile) int source=sys_open(SourceFile,O_RDONLY,0); int goal=sys_open(GoalFile,O_WRONLY|O_CREAT|O_TRUNC,0600); char buff4096; mm_segment_t fs; fs = get_fs(); set_fs(get_ds(); int i; if(source0 & goal0) 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) 测试程序#include #include #include int main() syscall(317,main.c,yyk.text); return 0;4.3 实验三4.3.1 实验规定掌握增长设备驱动程序的措施。通过模块措施,增长一种新的设备驱动程序,其功能可以简朴。(实现字符设备的驱动)4.3.2 具体实现(1)Linux核心是一种monolithic类型的内核,即单一的大核心,此外一种形式是MicroKernel,核心的所有功能部件都被拆成独立部分, 这些部分之间通过严格的通讯机制进行联系。Linux内核是一种整体构造,因此向内核添加任何东西.或者删除某些功能,都十分困难 。为理解决这个问题,引入了模块机制,从而可以动态的在内核中添加或者删除模块。模块一旦被插入内核,就和内核其她部分同样。Linux内核中的设备驱动程序是一组常驻内存的具有特权的共享库,是低档硬件解决例程。对顾客程序而言,设备驱动程序隐藏了设备的具体细节, 对多种不同设备提供了一致的接口,一般来说是把设备映射为一种特殊的设备文 件,顾客程序可以像对其他文献同样对此设备文献进行操作。Linux支持3种设备:字符设备、块设备和网络设备。设备由一种主设备号和一种次设备号标记。主设备号唯一标记了设备类型, 即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释 ,一般用于辨认在若干也许的硬件设备中,I/O祈求所波及到的那个设备。典型的Linux模块实现机制有如下几步:注册设备:在系统初启或者加载模块的时候,必须将设备登记到相应的设备数组,并返回主设备号。定义功能函数:对于每一种驱动函数来说,均有某些和此设备密切有关的功能函数。以最常用的块设备或者字符设备来说,都存在着诸如 open()、read()这一类的操作。当系统调用这些调用时,将自动的使用驱动函数中特定的模块来实现具体的操作。卸载设备:在不用这个设备时,可以将它卸载,重要是从/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:#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 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 *, const 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 (*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文献系统,将使用此种函数指针替代ioctl 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 *); /打开 int (*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); /异步刷新待解决的数据 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 *, 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); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock *); ;子功能函数具体代码见Error! Reference source not found.。(4) 设备驱动程序安装 make clean,清除make产生的残留 make,重新调用Makefile编译设备驱动程序 insmod -f MyDeviceDriver.ko,加载生成的 MyDeviceDriver.ko模块 cat /proc/devices,获取设备驱动程序的主设备号mknod /dev/MyDeviceDriver c 250 0,创立设备文献,250为主设备号,0为从设备号(5) 测试驱动程序此设备驱动程序实现的功能是将一种字符串中内容拷贝到此外一种字符串中。测试程序编写完毕后,在终端输入gcc test.c -o test进行编译。测试成果如下:具体代码见Error! Reference source not found.。4.3.3 源代码(1) 设备驱动程序#include #include #include #include #include #include #include #include #define DEV_SIZE 102400 /设备申请的最大内存空间struct Device char *data;/数组指针,用于寄存从顾客读入的数据 long size;/存储的数据长度*devp;struct cdev cdev;/字符设备构造体static int devNum_major = 0;/主设备号变量/相应顾客态的lseekstatic loff_t my_llseek(struct file *file,loff_t offset, int whence) loff_t cfo=0;/文献目前偏移量,current file offset switch(whence) case 0:/SEEK_SET cfo=offset;break;case 1:/SEEK_CUR cfo=file-f_pos+offset;break;case 2:/SEEK_END cfo=DEV_SIZE-1+offset;break; if (cfoDEV_SIZE)/文献偏移量越界 return -EINVAL; file-f_pos = cfo; return cfo;/相应顾客态的read,写数据到顾客空间static ssize_t my_read(struct file *file, char _user *buf, size_t count, loff_t *p_cfo) int val = 0; struct Device *dev = file-private_data; /设备描述构造体指针,获取设备信息 if (copy_to_user(buf, (void*)(dev-data + *p_cfo), count)/如果成功返回0;如果失败,返回未完毕copy的长度 val = -EFAULT; else *p_cfo += count;/copy成功,文献偏移量加上count val = count; return val;/相应顾客态的write,从顾客空间读入数据static ssize_t my_write(struct file *file, const char _user *buf, size_t count, loff_t *p_cfo) int val = 0; struct Device *dev = file-private_data; if (copy_from_user(dev-data + *p_cfo, buf, count)/如果成功返回0;如果失败,返回未完毕copy的长度 val = -EFAULT; else *p_cfo += count;/copy成功,文献偏移量加上count val = count; return val;static int my_open(struct inode *inode, struct file *file) file-private_data = devp; return 0;struct file_operations fops= .owner = THIS_MODULE, .llseek = my_llseek, .read = my_read, .write = my_write, .open = my_open,;int init_module(void)int dev_num;dev_num = register_chrdev(0,MyDeviceDriver,&fops);if (dev_num 0) printk(KERN_INFO MyDeviceDriver: FAIL to get major numbern);return dev_num;if (devNum_major = 0) devNum_major = dev_num; /初始化cdev构造 cdev_init(&cdev, &fops); cdev.owner = THIS_MODULE; cdev.ops = &fops; cdev_add(&cdev,MKDEV(devNum_major, 0), 1);/注册1个字符设备 /为设备描述构造体分派内存 devp = kmalloc(sizeof(struct Device), GFP_KERNEL); if (!devp) dev_num = -ENOMEM; printk(KERN_INFO MyDeviceDriver: FAIL to get memoryn); return dev_num; (*devp).size = DEV_SIZE; (*devp).data = kmalloc(DEV_SIZE, GFP_KERNEL); memset(*devp).data, 0, (*devp).size);/初始化为0 return 0;void cleanup_module(void)cdev_del(&cdev);/注销设备 kfree(devp);/注销设备构造体 kfree(*devp).data);/注销设备内存空间 unregister_chrdev(devNum_major,MyDeviceDriver);/卸载主设备号MODULE_LICENSE(GPL);(2) 驱动程序测试程序#include #include #include #define BUFFER_SIZE 102400int main(void)int dev,i=0;char c; char sourceBUFFER_SIZE;/写入MyDeviceDriver设备的内容 char goalBUFFER_SIZE; /MyDeviceDriver设备的内容读入到该goal中printf(input the string you want to write in your device:n);while(c=getchar()!=n)sourcei+=c;printf(n); if(dev=open(/dev/MyDeviceDriver,O_RDWR)=-1) /打开MyDeviceDriver设备失败 printf(FAIL to open MyDeviceDriver!n);else/成功 printf(SUCCESS to open MyDeviceDriver!n); printf(source:n%snn,source); write(dev,source,sizeof(source); /把source中的内容写入MyDeviceDriver设备 lseek(dev,0,SEEK_SET); /把文献指针定位到文献开始的位置 read(dev,goal,sizeof(source); /把MyDeviceDriver设备中的内容读入到goal中 printf(goal:n%snn,goal); return 0;4.4 实验四实验四有两个选做题目,分别是proc文献监控系统和小型文献系统,本次实验我选择的题目是proc文献监控系统。4.4.1 实验规定理解/proc文献的特点和使用措施;监控系统状态,显示系统中若干部件使用状态;用图形界面实现系统监控状态。4.4.2 具体实现(1)/proc文献系统的特点Linux的PROC文献系统是进程文献系统和内核文献系统的构成的复合体,是将内核数据对象化为文献形式进行存取的一种内存文献系统,是监控内核的一种顾客接口。它拥有某些特殊的文献(纯文本),从中可以获取系统状态信息。(2)功能清单获取并显示主机名,与之有关的proc文献为/proc/sys/kernel/hostname;获取并显示系统启动的时间,与之有关的proc文献为/proc/uptime;显示系统到目前为止持续运营的时间,与之有关的proc文献为/proc/uptime;显示系统的版本号,与之有关的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文献为/proc/stat;内存和互换分区的使用率的图形化显示(2分钟内的历史曲线),与之有关的proc文献为/proc/meminfo;在状态栏显示目前时间,未使用到/proc中的文献;在状态栏显示目前CPU使用率,与之有关的proc文献为/proc/stat;在状态栏显示目前内存使用状况,与之有关的proc文献为/proc/meminfo;用新线程运营一种其她程序,未使用到/proc中的文献;关机功能,未使用到/proc中的文献;(3)功能实现获取并显示主机名用fopen函数打开/proc/sys/kernel/hostname文献,然后以文献指针为输入流,用fgets从其中读出一行字符涉及主机名,然后用格式化输出函数sscanf函数输出一种字符串,即主机名。获取并显示系统启动的时间从文献/proc/uptime中获取系统启动到目前的运营时间(单位是s),然后调用time函数获取系统目前时间(单位是s),用目前时间秒数减去运营时间秒数即为系统启动的时间秒数,然后调用localtime函数将系统启动时间秒数转换成tm构造体类型的变量,该变量中的成员涉及年份、月份、日期、星期几、时、分、秒等,再调用输出函数输出即可。显示系统到目前为止持续运营的时间用fopen函数打开/proc/uptime文献,然后以文献指针为输入流,用fgets从其中读出一行字符涉及系统运营时间,然后用格式化输入函数sscanf从读取出的字符流中输入一种float类型的数到runtime,即系统运营的时间。显示系统的版本号从/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease中读取系统类型(例如linux)和系统内核版本号,解决措施和获取系统运营时间的措施同样。得到系统类型和系统内核版本号之后,调用QString类的措施arg将两个字符串连接起来,再输出显示即可。显示CPU的型号和主频大小打开/proc/cpuinfo文献后发现CPU有四个,相似的型号,不同的主频,后来才弄清晰所谓的四个CPU是CPU的四个核心,而“主频”并不是主频,而是目前时刻该核心所使用的CPU核心频率,随时间而变化的。弄清晰文献中的内容的含义之后,开始解决/proc/cpuinfo,从中读取CPU的型号和频率。解决这个文献没有用到fopen等函数,而是使用了Qt自带的两个类QFile和QTextStream,定义一种QFile类型的变量file,并用途径名“/proc/cpuinfo”初始化该变量,其作用是以只读方式打开文献/proc/cpuinfo,然后以file的地址作为参数初始化QTextStream类型的变量stream,其作用是将/proc/cpuinfo文献中的内容以字符流的形式存入变量stream中,相称于一种文本流。由于CPU的型号是同样的,因此只读取第一种型号名称即可,根据CPU型号名称所在的行,采用while循环读取stream中的内容,每次读取一行,当行数等于CPU型号所在行时,将读取
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!