中原工学院操作系统实验报告

  • 格式:doc
  • 大小:2.15 MB
  • 文档页数:23

计算机操作系统实验报告专业:网络工程班级: 162班学号:学生姓名:指导教师:2019/06/06目录实验一进程控制 (3)一、实验目的: (3)二、实验平台: (4)三、实验内容: (4)实验结果 (5)单线程执行结果: (7)实验总结 (8)实验二进程同步 (8)一、实验目的: (8)二、实验平台: (8)三、实验内容: (9)执行结果 (12)实验总结 (12)实验三添加内核模块 (12)一、实验目的: (12)二、实验平台: (13)三、实验内容: (13)代码: (14)Makefile代码: (15)processinfo文件源代码: (17)Makefile文件源代码: (18)实验总结 (20)实验四统计操作系统缺页次数 (20)实验目的 (20)实验内容 (21)实验过程 (21)1. 修改内核源代码,添加统计变量 (21)2. 配置编译新内核 (23)3. 编译内核和模块 (24)4. 安装新内核模块和新内核 (24)5. 编写读取pfcount值的模块代码 (25)6.编译、构建内核模块 (26)7.加载模块到内核中 (26)实验总结 (27)实验五 EXT4文件系统结构分析 (27)一、实验目的: (27)二、实验平台: (27)三、实验内容: (27)实验总结 (31)实验一进程控制一、实验目的:加深对进程概念的理解,明确进程和程序的区别;掌握Linux操作系统的进程创建和终止操作,体会父进程和子进程的关系及进程状态的变化;进一步认识并发执行的实质,编写并发程序。

二、实验平台:虚拟机:VMWare9以上操作系统:以上编辑器:Gedit | Vim编译器:Gcc三、实验内容:(1)编写一段程序,使用系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示“身份信息”:父进程显示“Parent process! PID=xxx1 PPID=xxx2”;子进程显示“Childx process! PID=xxx PPID=xxx”。

多运行几次,观察记录屏幕上的显示结果,并分析原因。

说明:xxx1为进程号,用getpid()函数可获取进程号;xxx2为父进程号,用getppid()函数可获取父进程号;Childx中x为1和2,用来区别两个子进程;wait()函数用来避免父进程在子进程终止之前终止。

程序源码:#include<>#include<>#include<>#define NUM 2int main(void){pid_t pid1,pid2;if((pid1=fork())<0){printf("创建进程1失败");}else{if(pid1==0){testChild2 process: PID=2527 PPID=2525Child1 process: PID=2526 PPID=2525Parent process: PID=2525 PPID=2127whtcmiss@whtcmiss-VirtualBox:~/Desktop$ ./testChild2 process: PID=2530 PPID=2528Child1 process: PID=2529 PPID=2528Parent process: PID=2528 PPID=2127whtcmiss@whtcmiss-VirtualBox:~/Desktop$ ./testChild2 process: PID=2533 PPID=2531Child1 process: PID=2532 PPID=2531Parent process: PID=2531 PPID=2127实验结果分析:第一次程序运行结果,两个子进程的PPID都是2525,是由同一个进程创建。

而父进程PID是2525,父进程PPID是2127,说明父进程也是一系统进程的子进程。

第二次程序运行结果,父进程PID是2528,PPID是2127,说明父进程是由同一进程创建的,父进程也是以子进程的方式存在,且进程ID是逐渐递增的。

(2)fork()和exec()系列函数能同时运行多个程序,利用上述函数将下面单进程顺序执行的程序改造成可并发执行3个进程的程序;并用time命令获取程序的执行时间,比较单进程和多进程运行时间,并分析原因。

single单线程执行结果:多线程代码:##include <>#include<>#include<>#define NUM 5int main(void){pid_t pid[3];int i;for(i=1;i<=3;i++){pid[i-1]=fork();if(pid[i-1]==0||pid[i-1]==-1)break;}if(pid[0]==0){execl("print","print","Good",NULL);}else {if(pid[1]==0){execl("print","print","Hello",NULL);}else{if(pid[2]==0){execl("print","print","0222",NULL);}wait();wait();wait();exit(0);}}return 0;}实验分析:第二个实验结果,第二个程序的多线程因为是并发执行,而且是有三个线程,所以在时间上几乎是单线程的1/3,而且因为是并发的,所以打印结果是无序的。

实验总结本次实验首先要明确进程和程序的区别,我通过在Linux操作系统的进程创建和终止操作,运行父进程和子进程,查看运行结果和进程状态的变化。

实验过程中也了解了父进程与子进程的运行过程及其机制。

实验二进程同步一、实验目的:掌握基本的同步算法,理解经典进程同步问题的本质;学习使用Linux的进程同步机制,掌握相关API的使用方法;能利用信号量机制,采用多种同步算法实现不会发生死锁的哲学家进餐程序。

二、实验平台:虚拟机:VMWare9以上操作系统:以上编辑器:Gedit | Vim编译器:Gcc三、实验内容:(1)以哲学家进餐模型为依据,在Linux控制台环境下创建5个进程,用semget函数创建一个信号量集(5个信号量,初值为1),模拟哲学家的思考和进餐行为:每一位哲学家饥饿时,先拿起左手筷子,再拿起右手筷子;筷子是临界资源,为每一支筷子定义1个互斥信号量;想拿到筷子需要先对信号量做P操作,使用完释放筷子对信号量做V操作。

伪代码描述:semaphore chopstick[5]={1,1,1,1,1};•第i位哲学家的活动可描述为:do{printf("%d is thinking\n",i);printf("%d is hungry\n",i);wait(chopstick[i]);o文件:使用命令载入模块,如图:使用lsmod命令显示载入系统的模块,如图:使用dmesg命令查看到系统的内核模块信息,如图:使用sudo rrmod hello命令卸载该模块,如图:(3)利用内核模块编程,在/proc目录下用自己的学号创建一个目录,如/proc/4101然后在学号目录下创建一个processinfo文件,如/proc/4101/processinfo,此文件为只读文件,用于显示所有内核进程的程序名、PID号和进程状态。

主要步骤:修改(2)中readprocess模块,在模块初始化函数中创建目录及proc文件,并定义产生proc文件内容的函数(获取进程信息);在卸载模块函数中删除相应的proc文件及目录;修改Makefile文件,编译、安装模块;执行cat /proc/4101/processinfo命令,查看进程信息。

processinfo文件源代码:#include<linux/>#include<linux/>#include<linux/>#include<linux/>#include<linux/>MODULE_LICENSE("GPL");static int mod_init_readprocess(void);static void mod_exit_readprocess(void);module_init(mod_init_readprocess);module_exit(mod_exit_readprocess);struct proc_dir_entry *feeyu_dir,*processinfo_file;int processinfo_read_procmem(char *page,char **start,off_t offset,int count,int *eof,void *data);int mod_init_readprocess(void){p rintk(KERN_INFO"-------Let's Go-------\n");f eeyu_dir=proc_mkdir("4419",NULL);p rocessinfo_file=create_proc_read_entry("processinfo",0,cg_dir,processinfo_ read_procmem, NULL );r eturn 0;}void mod_exit_readprocess(void){r emove_proc_entry("processinfo",cg_dir);r emove_proc_entry("4419",NULL);p rintk(KERN_INFO"--------Thank You--------\n");}int processinfo_read_procmem(char *page,char **start,off_t offset,int count,int *eof,void *data){i nt len=0;s truct task_struct *p;p rintk("所有内核进程信息:\n");f or_each_process(p){len+=sprintf(page+len,"NAME:%sPID:%dSTATE:%ld\n",p->comm,p->pid,p->state); }r eturn len;}Makefile文件源代码:ifneq ($(KERNELRELEASE),)o bj-m:=elseK DIR:= /lib/modules/$(shell uname -r)/buildP WD:= $(shell pwd)default:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:$(MAKE) -C $(KDIR) M=$(PWD) cleanEndif加载模块:查看模块是否存在:查看模块信息:查看进程信息:卸载模块后实验总结这次实验内容较多,重要是通过一些命令和代码对内核模块的进程进行操作。