《操作系统课程设计-后面.doc》由会员分享,可在线阅读,更多相关《操作系统课程设计-后面.doc(18页珍藏版)》请在金锄头文库上搜索。
1、第一章:设计内容及要求一、课程设计的目的本课程是操作系统课程的重要组成部分,通过本课程的学习,使学生能更进一步地理解操作系统的设计和实现思路。掌握操作系统主要原理和算法。培养学生的实际运用操作系统原理分析解决问题的能力。二、课程设计的题目1. 进程管理仿真程序设计三、设计内容(一)进程管理仿真程序设计1.基本要求:设计一个仿真程序,仿真进程管理的五大功能,包括创建进程,用新进程替换当前进程映像,进程状态转换,进程调度,上下文切换。2.创新要求在基本要求达到后,可以进行创新设计。3.设计方法和基本原理 设计一个PCB数据结构,该结构包含进程的所有信息,如进程号pid ,父进程号ppid,进程优先
2、数,进程运行时间,进程时间片,程序计数器值,累加器值等。 设计一个kernel程序,该程序分配一个大的内存空间,用于存放模拟进程。 在kernel中设计一个解释函数,解释执行模拟程序中的语句。 设计一个命令解释程序,接收用户命令,发送给kernel。 在kernel中设计一个调度函数,调度模拟程序执行。 在kernel中设计一个上下文切换函数,负责模拟程序的切换。Kernel中设置一个定时器,负责处理时间片。用伪指令编写系统信息程序和用户测试程序。 第二章:设计说明一、问题描述:系统由4种程序组成,它们是进程管理程序(kernel)、命令解释程序(commander)、系统信息程序( repo
3、rter)、用户程序(Application)。系统内有3种进程(下称模拟进程),它们是: 命令解释进程(commander),系统信息进程( reporter),用户进程(Application)。Kernel程序首先运行。Kernel启动后,创建commander进程。Kernel程序根据需要创建reporter进程和Application进程。Kernel负责维护6个数据结构,包括时间 (Time), 处理器状态(CPUstate),进程表 (PCBTable), 就绪队列(ReadyState),等待队列(BlockedState),运行进程(RunningState)。系统采用时间轮
4、转和优先级调度混合算法。优先级以优先数表示,优先数越大则优先级越高。调度时,就绪队列中优先数最大的进程优先运行,相同优先数进程按FIFO方式调度。进程运行一个时间片以后,其优先数数减1(即降低一级);进程在就绪队列中等待3个时间片以后,其优先数加1。二、方案设计: 设计一个PCB数据结构,该结构包含进程的所有信息,如进程号pid ,父进程号ppid,进程优先数,进程运行时间,进程时间片,程序计数器值,累加器值等。 设计一个kernel程序,该程序分配一个大的内存空间,用于存放模拟进程。 在kernel中设计一个解释函数,解释执行模拟程序中的语句。 设计一个命令解释程序,接收用户命令,发送给ke
5、rnel。 在kernel中设计一个调度函数,调度模拟程序执行。 在kernel中设计一个上下文切换函数,负责模拟程序的切换。Kernel中设置一个定时器,负责处理时间片。用伪指令编写系统信息程序和用户测试程序。三、设计分析:代码解释:1. 创建简单虚拟内核其实,若只考虑功能实现,我们完全可以不定义虚拟CPU。所以,为了简单又简单,我们不定义虚拟CPU,而直接通过进程PCB进行计算。但这不便于同学们理解上下文切换。有兴趣的同学可以考虑定义一个虚拟CPU(参见“虚拟内核(含虚拟CPU)设计提示.doc”)。编写编译程序:(1)定义指令#define MOV 01 /传送指令:立即数赋值给寄存器A
6、#define ADD 02 /加法指令:寄存器A加立即数#define OUT 80 /输出指令: 寄存器A的值输出到端口(端口号01-表示显示器)2. 定义PCB结构typedef struct short A; /寄存器Aint PC; /程序计数器PCchar *addr;/程序加载起始地址int length;/程序大小PCB;#define MAX_PID 10 /假设系统可同时运行10个进程PCB pcbsMAX_PID; /定义PCB结构数组,用于存放所有的PCB3. 定义系统变量定义一个全局变量作为系统变量:int cur_pid; /当前_进程号初始化:cur_pid=0;
7、4. 加载用户程序打开字节码文件,求字节码文件长度。获取当前进程的PCB: PCB *pcb=pcbs+cur_pid;分配加载内存:pcb-addr=(char *)malloc(字节码文件长度);字节码文件读入到pcb-addr;登记加载信息:pcb-A=0; pcb-PC=0; pcb-length=字节码文件长度;5. 编写执行指令的函数获取当前进程的PCB: PCB *pcb=pcbs+cur_pid;在pcb-addr+pcb-PC所指的单元取指令,执行该指令。修改程序计数器:pcb-PC+=刚才执行的指令长度;比如,假设PC所指的字节码为020F00。可以这么些执行代码:shor
8、t op_data; /注意,操作数为16位整数,所以要定义为shortchar cmd;cmd= *(pcb-addr+pcb-PC); /取指令if(cmd=0x02) /执行指令op_data= *(short*)(pcb-addr+pcb-PC+1); /取操作数pcb-A+= op_data; /操作数加到寄存器Apcb-PC+=3;/修改程序计数器,使之指向下一条指令5. 扩展PCB结构添加新的结构成员typedef struct int A; /寄存器Aint PC; /程序计数器PCchar *addr;/程序加载起始地址int length;/程序大小/以下为新增成员int
9、pid;/进程号,值-1MAX_PID,-1表示无进程int ppid;/父进程号int gpid;/进程组号char state;/进程状态:01-新建,02-就绪,03-运行, 04-等待,/ 05-完成int slice;/时间片大小。为了简单,假设为“指令条数/时间片”int B; /寄存器Bint F; /寄存器Fchar *addr;/程序加载起始地址char priority;/优先数, 值为0-31,其中31为最高级char last; /上次运行的时间,调度时要用此时间PCB;6.扩展系统变量增加两个全局变量,作为系统变量:int max_pid; /最大_进程号unsign
10、ed int tick; /时间嘀嗒数,假设每条指令占一个机器周期,嘀嗒一次/= 下面3个变量暂不使用 =long intf; /中断标志(可管理32个中断)/以下成员先暂时定义为字节流,以后要把它们改为结构体char *sys_stack;/系统栈,存放系统参数。char *usr_stack; /用户栈,存放用户私有数据,如存放函数参数,返回地址等等。char *signal;/信号,暂时这样定义,以后要把它改为结构体/= 下面3个变量暂不使用 =初始化:max_pid=0; tick=0;7.优先级设计for(int p=0;ppriority-=2;elsepcbx-priority+
11、=2;for(int j=0;jstate=0) coutendl; cout进程j+1的优先级为:priorityendl; else coutendl; cout进程j+1已经结束!endl; 8.进程按优先级调度运行while(1)cur_pid=0; for(int q=0;qprioritypriority) cur_pid=q;PCB *pcb=pcbs+cur_pid;for(int i=0;iclise;i+)exeInstruction(cur_pid);/执行指令 if(pcb-PC=pcb-length)/执行完毕 if(pcb-state=0) pcb-state=1;
12、 /标志位置1,表示进程结束 pcb-priority=0; /优先级置0 delete pcb-addr;/回收内存 flag+; int z; coutz; if(z=1) system(cls); if(flag=argc-1) return 0;第三章:测试1.用户设计各进程的优先级和时间片:2.程序按各进程的优先级完成调度:本次运行进程所用时间片以及显示全部进程状态3.运行过的进程优先级减少2,其他进程优先级增加2总测试效果:第四章:总结 这次的程序设计和以往的不同,原来的课程设计主要是了解题目要求,然后自己按自己的思路设计的自己的算法编写代码即可,但是这次要按照操作系统本来的逻辑编写,初始有点不太适应,但是经过对题目的分析,发现固然这次的题目固定了我们的算法,但是也同时使得设计更加简便,只