通用处理机 操作系统课程设计报告

合集下载

操作系统课程设计实验报告

操作系统课程设计实验报告

操作系统课程设计实验报告操作系统课程设计实验报告引言:操作系统是计算机科学中的重要课程,通过实验设计,可以帮助学生更好地理解操作系统的原理和实践。

本文将结合我们在操作系统课程设计实验中的经验,探讨实验设计的目的、实验过程和实验结果,以及对操作系统的理解和应用。

一、实验设计目的操作系统课程设计实验的目的是帮助学生深入理解操作系统的工作原理和实际应用。

通过设计和实现一个简单的操作系统,学生可以更好地掌握操作系统的各个组成部分,如进程管理、内存管理、文件系统等。

同时,实验设计还可以培养学生的动手能力和问题解决能力,提高他们对计算机系统的整体把握能力。

二、实验过程1. 实验准备在进行操作系统课程设计实验之前,我们需要对操作系统的基本概念和原理进行学习和理解。

同时,还需要掌握一些编程语言和工具,如C语言、汇编语言和调试工具等。

这些准备工作可以帮助我们更好地进行实验设计和实现。

2. 实验设计根据实验要求和目标,我们设计了一个简单的操作系统实验项目。

该项目包括进程管理、内存管理和文件系统三个主要模块。

在进程管理模块中,我们设计了进程创建、调度和终止等功能;在内存管理模块中,我们设计了内存分配和回收等功能;在文件系统模块中,我们设计了文件的创建、读写和删除等功能。

通过这些模块的设计和实现,我们可以全面了解操作系统的各个方面。

3. 实验实现在进行实验实现时,我们采用了分阶段的方法。

首先,我们实现了进程管理模块。

通过编写相应的代码和进行调试,我们成功地实现了进程的创建、调度和终止等功能。

接下来,我们实现了内存管理模块。

通过分配和回收内存空间,我们可以更好地管理系统的内存资源。

最后,我们实现了文件系统模块。

通过设计文件的读写和删除等功能,我们可以更好地管理系统中的文件资源。

三、实验结果通过实验设计和实现,我们获得了一些有意义的结果。

首先,我们成功地实现了一个简单的操作系统,具备了进程管理、内存管理和文件系统等基本功能。

操作系统课程设计实验报告(附思考题答案)

操作系统课程设计实验报告(附思考题答案)

操作系统课程设计实验报告(附思考题答案)课程设计(综合实验)报告( 2015 -- 2016 年度第 1 学期)名称:操作系统综合实验题目:oslab综合实验院系:计算机系班级:学号:学生姓名:指导教师:设计周数:分散进行成绩:日期:2015 年10 月29 日一、综合实验的目的与要求1. 理解和掌握操作系统的基本概念、基本组成与工作原理;2. 理解和掌握操作系统中主要功能模块的工作原理及其实现算法;3. 掌握软件模块设计技能;熟悉并能较好地利用软件开发环境独立编程、调试和分析程序运行情况,逐渐形成创新思维和从事系统软件的研究和开发能力。

二、实验正文实验1:实验环境的使用1.1实验目的:1.熟悉操作系统集成实验环境OS Lab 的基本使用方法。

2.练习编译、调试EOS 操作系统内核以及EOS 应用程序。

1.2实验内容:1.启动OS Lab2.学习OS Lab 的基本用法● 新建 Windows 控制台应用程序项目(1)在“文件”菜单中选择“新建”,然后单击“项目”。

(2)在“新建项目”对话框中,选择项目模板“控制台应用程序(c)”。

(3)在“名称”中输入新项目使用的文件夹名称“oslab ”。

(4)在“位置”中输入新项目保存在磁盘上的位置“C:\test ”。

(5)点击“确定”按钮。

● 生成、执行项目●3.EOS 内核项目的生成和调试● 新建 EOS 内核项目并按F7生成项目● 调试项目● 查看软盘镜像文件中的内容、EOS SDK (Software Development Kit )文件夹4.EOS 应用程序项目的生成和调试● 新建 EOS 应用程序项目● 修改 EOS 应用程序项目名称使用断点中断执行查看变量的值5.退出OS Lab6.保存EOS内核项目1.3思考与练习●在实验1中,生成EOS SDK文件夹的目的和作用是什么?答:SDK文件夹中提供了开发EOS应用程序需要的所有文件。

debug文件夹是在使用debug配置生成项目时生成的,其中存放了调试版本的EOS二进制文件。

操作系统课程设计报告

操作系统课程设计报告

一、课程设计任务划分二、根本原理〔一〕页面置换算法定义在地址映射过程中,假设在页面中发现所要访问的页面不再内存中,那么产生缺页中断。

当发生缺页中断时操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。

而用来选择淘汰哪一页的规那么叫做页面置换算法。

〔二〕所使用的算法1) 最正确置换算法(OPT):将以后永不使用的或许是在最长(未来)时间内不再被访问的页面换出。

2) 先进先出算法(FIFO):淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。

3) 最近最久未使用算法(LRU):淘汰最近最久未被使用的页面。

〔三〕设计思想选择置换算法,先输入所有页面号,为系统分配物理块,依次进行置换:OPT根本思想:是用一维数组page[pIZE]存储页面号序列,memery[mIZE]是存储装入物理块中的页面。

数组ne某t[mIZE]记录物理块中对应页面的最后访问时间。

每当发生缺页时,就从物理块中找出最后访问时间最大的页面,调出该页,换入所缺的页面。

FIFO根本思想:是用一维数组page[pIZE]存储页面号序列,memery[mIZE]是存储装入物理块中的页面。

数组flag[10]标记页面的访问时间。

每当使用页面时,刷新访问时间。

发生缺页时,就从物理块中页面标记最小的一页,调出该页,换入所缺的页面。

三、根本思路实验环境:vc++,编程语言:c语言 #include #include /某全局变量某/int mIZE; /某物理块数某/int pIZE; /某页面号引用串个数某/tatic int memery[10]={0}; /某物理块中的页号某/ tatic int page[100]={0}; /某页面号引用串某/ tatic int temp[100][10]={0}; /某辅助数组某/ /某置换算法函数某/ void FIFO(); void LRU(); void OPT(); /某辅助函数某/void print(unigned int t); void deignBy(); void download();void mDelay(unigned int Delay); /某主函数某/ void main() {canf("%1d",&page[i]); download(); ytem("cl"); ytem("color 0E"); do{ put("输入的页面号引用串为:"); for(k=0;k<=(pIZE-1)/20;k++){ for(i=20某k;(i<pize)&&(i<20某(k+1));i++) 20="=0)||(((i+1))&&</p">(i==pIZE-1))) printf("%d ",page[i]); ele printf("%d ",page[i]); } } printf("某某某某某某某某某某某某某某某某某某某某某某某 "); printf("某请选择页面置换算法:某 "); printf("某 ----------------------------------------- 某 ");printf("某 1.先进先出(FIFO) 2.最近最久未使用(LRU) 某 "); printf("某 3.最正确(OPT) 4.退出某 "); printf("某某某某某某某某某某某某某某某某某某某某某某某 "); printf("请选择操作:[ ]"); canf("%d",&code); witch(code) { cae 1:FIFO(); break; cae 2:LRU(); break; cae 3:OPT(); break; cae 4: ytem("cl"); ytem("color 0A"); deignBy(); /某显示设计者信息后退出某/ printf("┃谢谢使用页面置换算法演示器!ytem("cl"); }while (code!=4); getch(); }/某载入数据某/ void download() { int i; ytem("color 0D");printf("╔════════════╗ "); printf("║正在载入数据,请稍候 !!!║ "); printf("╚════════════╝ "); printf("Loading... "); printf("for(i=0;i<51;i++) printf(""); for(i=0;i<50;i++) { mDelay((pIZE+mIZE)/2);printf(">"); } printf(" Finih. 载入成功,按任意键进入置换算法选择界面:/某设置延迟某/void mDelay(unigned int Delay) {unigned int i;for(;Delay>0;Delay--) { for(i=0;i<124;i++) { printf(" "); } } }/某显示设计者信息某/ void deignBy(){ printf("┏━━━━━━━━━━━━━━━━━━━━┓ "); printf("┃页面置换算法┃ "); printf("┃ 12级1班┃ ");O");printf("┃姓名:张海洋,李奔┃ ");printf("┣━━━━━━━━━━━━━━━━━━━━┫ "); }void print(unigned int t) { int i,j,k,l; int flag; for(k=0;k<=(pIZE-1)/20;k++) { for(i=20某k;(i<pize)&&(i<20某(k+1));i++) 20="=0)||(((i+1))&&(i==pIZE-1)))" ele="" d="" j="0;j<mIZE;j++)" i="">=j) printf(" |%d|",temp[i][j]); ele printf(" | |"); } for(i=mIZE+20某k;(i<pize)&&(i<20某(k+1));i++) {=""for(flag="0,l=0;l<mIZE;l++)" if(temp[i][l]="=temp[i-1][l])" flag++;=""if(flag="=mIZE)/某页面在物理块中某/" printf("="" ");="" ele=""|%d|",temp[i][j]);="" }="" 某每行显示20个某="" if(i="=0)" continue;="" printf(" ");="" printf("---------------------------------------- ");="" printf("缺页次数:%d",t+mize);="" printf("缺页率:%d="" %d ",t+mize,pize);<="" p="">printf("置换次数:%d ",t); printf("访问命中率:%d%% ",(pIZE-(t+mIZE))某100/pIZE); printf("---------------------------------------- "); }/某先进先出页面置换算法某/ void FIFO() {int memery[10]={0};int ma某=0; /某记录换出页某/ int count=0; /某记录置换次数某/ /某前mIZE 个数直接放入某/ for(i=0;i<mize;i++) {<="" p="">for(j=0;j<mize;j++) temp[i][j]="memery[j];" }<="" p="">for(i=mIZE;i<pize;i++) {="" 某判断新页面号是否在物理块中某=""for(j="0,k=0;j<mIZE;j++)" {<="" p="">if(memery[j]!=page[i]) k++;}if(k==mIZE) /某如果不在物理块中某/ {count++; /某计算换出页某//某最近最久未使用置换算法某/ void LRU() {int memery[10]={0};int flag[10]={0}; /某记录页面的访问时间某/ int i,j,k,m;int ma某=0; /某记录换出页某/ int count=0; /某记录置换次数某/ /某前mIZE 个数直接放入某/ for(i=0;i<mize;i++) {<="" p="">memery[i]=page[i]; flag[i]=i;for(j=0;j<mize;j++) temp[i][j]="memery[j];" }<="" p="">for(i=mIZE;i<pize;i++) {="" 某判断新页面号是否在物理块中某=""for(j="0,k=0;j<mIZE;j++)" {<="" p="">if(memery[j]!=page[i]) k++; ele flag[j]=i; /某刷新该页的访问时间某/ }if(k==mIZE) /某如果不在物理块中某/ {count++; /某计算换出页某/ma某=flag[0]<flag[1] 0:1; for(m="2;m<mIZE;m++)" if(flag[m]flag[ma某]=i; /某记录该页的访问时间某/ for(j=0;j<mize;j++)temp[i][j]="memery[j];" }="" ele="" {<="" p="">/某最正确置换算法某/ void OPT() {int memery[10]={0};int ne某t[10]={0}; /某记录下一次访问时间某/ int i,j,k,l,m;int ma某; /某记录换出页某/int count=0; /某记录置换次数某/ /某前mIZE个数直接放入某/for(i=0;i<mize;i++) {<="" p="">memery[i]=page[i]; for(j=0;j<mize;j++) temp[i][j]="memery[j];" }<="" p=""> for(i=mIZE;i<pize;i++) {<="" p="">/某判断新页面号是否在物理块中某/ for(j=0,k=0;j<mize;j++) {<="" p="">if(memery[j]!=page[i]) k++; }if(k==mIZE) /某如果不在物理块中某/ { count++; /某得到物理快中各页下一次访问时间某/ for(m=0;m=ne某t[1] 0:1; for(m=2;mne某t[ma某]) ma某=m; /某下一次访问时间都为pIZE,那么置换物理块中第一个某/ memery[ma某]=page[i]; for(j=0;j<mize;j++) temp[i][j]="memery[j];" }="" ele="" {<="" p="">四、调试及实验结果第一组数据:1.运行结果2. 按任意键进行初始化:3. 载入数据:4. 进入置换算法选择界面:5.运算中延迟操作:6.三种算法演示结果7.退出算法第二组数据:1.运行结果2.按任意键进行初始化:3.载入数据:4.进入置换算法选择界面:5.运算中延迟操作:6. 三种算法演示结果7.退出算法五、个人体会由于时间有限,本次设计完成的并不是很完美,下面从以下几点来说明本次课程设计的个人体会:1.本次课程设计中做的比拟好的地方:做的.好的地方就是在于对题目意思的正确理解,以及在此根底上的模型设计。

操作系统 课程设计 处理机调度 图形界面 完整报告

操作系统 课程设计 处理机调度 图形界面 完整报告

目录第一章概述 (1)1.1需求分析 (1)1.2背景设计 (1)第二章概要设计 (2)第三章详细设计 (4)3.1高响应比调度算法 (4)3.2时间片轮转法 (5)3.3短进程优先法 (7)第四章调试分析与测试结果 (9)第五章总结 (13)第六章参考文献 (14)第七章附录 (15)第一章概述1.1需求分析进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用短作业优先调度算法,高响应比调度算法,时间片轮转调度算法实现进程调度。

可以手动阻塞与唤醒。

并用MFC实现图形界面。

本实验可加深对进程调度算法的理解。

1.2背景设计在OS中,调度的实质是一种资源分配,调度算法即指:根据系统的资源分配策略所规定的资源分配算法。

对于不同的系统和系统目标,通常采用不同的调度算法,如在批处理系统中,为照顾为数众多的短作业,采用短作业有限调度算法;在分时系统中,为保证系统具有合理的响应时间,采用轮转法进行调度。

采用算法时,则要考虑多方面因素,以便达到最佳效果。

第二章概要设计设计一个有多个进程共行的进程调度程序。

进程调度算法:短作业优先调度算法,高响应比调度算法,时间片轮转调度算法每个进程有一个进程控制块( PCB)表示。

进程控制块可以包含如下信息:进程名、优先数、到达时间、服务时间、进程状态等等。

struct progress{CString Name; //进程名称CString Start; //创建时间int ServiceT; //服务时间int RunningT; //消逝时间int RemainT;//剩余时间int id;//进程标识符CProgressCtrl* pro; //指向进度条的指针int Rp;//进程成为就绪进程的时间float prio;//进程优先权};进程的优先权为:响应时间/要求服务时间。

进程的运行时间以时间片为单位进行计算。

操作系统-课程设计报告-处理机调度程序

操作系统-课程设计报告-处理机调度程序

操作系统课程设计报告学校:广州大学学院:计算机科学与教育软件学院班级:计算机127班课题:处理机调度程序任课老师:陶文正、陈文彬姓名:黄俊鹏学号:1200002111班内序号:27成绩:日期:2015年1月6日一、设计目的在多道程序和多任务系统中,系统内同时处于就绪状态的进程可能有若干个。

也就是说能运行的进程数大于处理机个数。

为了使系统中的进程能有条不紊地工作,必须选用某种调度策略,选择一进程占用处理机。

要求学生设计一个模拟处理机调度算法,以巩固和加深处理机调度的概念。

二、设计要求1)进程调度算法包括:时间片轮转法,短作业优先算法,动态优先级算法。

2)可选择进程数量3)本程序包括三种算法,用C语言实现,执行时在主界面选择算法(可用函数实现)(进程数,运行时间,优先数由随机函数产生)执行,显示结果。

三、设计思路及算法思想1.界面菜单选项一级菜单提供2个选项:①自动生成进程数量②手动输入所需进程数量一级菜单选择完毕后进入二级菜单:①重新生成进程②时间片轮转法③短作业优先算法④动态优先级算法⑤退出程序2.调度算法程序所用PCB结构体需要用到的进程结构体如上图所示1)时间片轮转法主要是设置一个当前时间变量,curTime和时间片roundTime。

遍历进程组的时候,每运行一个进程,就把curTime += roundTime。

进程已运行时间加roundTime2)短作业优先算法遍历进程组,找到未运行完成并且运行时间最短的进程,让它一次运行完成,如此往复,直到所有进程都运行完成为止。

3)动态优先级算法做法跟短作业优先算法类似,此处主要是比较进程的优先数,优先级高者,先执行。

直到全部执行完毕。

当一个进程运行完毕后,适当增减其余进程的优先数,以达到动态调成优先级的效果。

3.程序流程图四、运行截图1)启动后输入5,生成5个进程2)输入1,选择时间片轮转法。

自动输出结果,分别是时间片为1和4的结果3)输入2,选择短作业优先算法4)输入3,选择动态优先级算法5)输入0,重新生成进程,再输入3,生成3个进程,选择2.短作业优先算法6)输入q,退出五、心得体会通过这次实验,让我对操作系统的进程调度有了更进一步的了解。

操作系统课程设计报告

操作系统课程设计报告

实践课设计报告课程名称操作系统课程设计模拟设计内存管理中的地址题目转换(动态分区、页式十进制)学院班级学号姓名指导教师年月日课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 模拟设计内存管理中的地址转换(动态分区、页式十进制)初始条件:1.预备内容:阅读操作系统的内存管理章节内容,理解动态分区、页式、段式和段页式存储管理的思想及相应的分配主存的过程。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.下列内部存储器管理中地址转换,在完成指定存储管理技术中的地址转换基础上还可以选择其它内部存储器管理中的地址转换进行模拟设计并实现:⑴动态分区方案,用最先适用算法对作业实施内存分配,然后把作业地址空间的某一逻辑地址转换成相应的物理地址。

能够处理以下的情形:输入某一逻辑地址,程序能判断地址的合法性,如果合法,计算并输出相应的物理地址。

如果不能计算出相应的物理地址,说明原因。

⑵页式存储管理中逻辑地址到物理地址的转换(十进制)。

能够处理以下的情形:输入某一十进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用十进制表示。

⑶页式存储管理中逻辑地址到物理地址的转换(八进制)。

能够处理以下的情形:输入某一八进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用八进制表示。

⑷页式存储管理中逻辑地址到物理地址的转换(十六进制)。

能够处理以下的情形:输入某一十六进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用十六进制表示。

⑸段式存储管理中逻辑地址到物理地址的转换。

能够处理以下的情形:指定内存的大小,进程的个数,每个进程的段数及段大小;能检查地址的合法性,如果合法进行转换,否则显示地址非法的原因。

⑹段页式存储管理中逻辑地址到物理地址的转换。

操作系统课程设计报告

操作系统课程设计报告

《操作系统课程设计》一、课程设计目的1、进程调度是处理机管理的核心内容。

2、本设计要求用C语言编写和调试一个简单的进程调度程序。

3、通过设计本可以加深理解有关进程控制块、进程队列的概念,并体会和了解最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法的具体实施办法。

二、课程设计主要内容1、项目名称设计一个有 N个进程共行的进程调度程序2、实验设备及环境:软件要求:WINDOWS NT 系列操作系统,VC、VB、TURBO C等多种程序设计开发工具。

硬件要求:P4 2.0以上CPU、256M、40G硬盘。

3、课程设计类型综合设计型4、课程设计内容与要求1)进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。

2)每个进程有一个进程控制块( PCB)表示。

进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。

3)进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。

进程的到达时间为进程输入的时间。

进程的运行时间以时间片为单位进行计算。

4)每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

5)就绪进程获得 CPU后都只能运行一个时间片。

用已占用CPU时间加1来表示。

如果运行一个时间片后,进程的已占用 CPU 时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。

6)每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。

7)重复以上过程,直到所要进程都完成为止。

5、课程设计方法及步骤1)充分了解各项设计要求。

深入理解有关进程控制块、进程队列的概念,并体会和了解最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法的具体实施办法。

操作系统-课程设计报告-处理机调度程序

操作系统-课程设计报告-处理机调度程序

操作系统课程设计报告学校:广州大学学院:计算机科学与教育软件学院班级:计算机127 班课题:处理机调度程序任课老师:陶文正、陈文彬姓名:黄俊鹏学号:1200002111班内序号:27成绩:日期:2015 年 1 月 6 日、设计目的在多道程序和多任务系统中,系统内同时处于就绪状态的进程可能有若干个。

也就是说能运行的进程数大于处理机个数。

为了使系统中的进程能有条不紊地工作,必须选用某种调度策略,选择一进程占用处理机。

要求学生设计一个模拟处理机调度算法,以巩固和加深处理机调度的概念。

、设计要求1)进程调度算法包括:时间片轮转法,短作业优先算法,动态优先级算法2)可选择进程数量3)本程序包括三种算法,用C 语言实现,执行时在主界面选择算法(可用函数实现)(进程数,运行时间,优先数由随机函数产生)执行,显示结果。

三、设计思路及算法思想1. 界面菜单选项一级菜单提供2 个选项:① 自动生成进程数量② 手动输入所需进程数量一级菜单选择完毕后进入二级菜单:①重新生成进程②时间片轮转法③短作业优先算法④动态优先级算法⑤退出程序2. 调度算法typedef st ruct char name;mr pri-ority; intrunnirtgrime;"肚先註 "运和时Eint arriveTiflie;"到达时剖int beg in Time;"幵皓时旬int TinishTiJiie: "尧成时列int cyclingTlme;double weigthC/clingTime:kint int >PCB;hadRunTimt;finish:"已经运行呼间/At否完咸程序所用PCB结构体需要用到的进程结构体如上图所示1)时间片轮转法主要是设置一个当前时间变量,curTime和时间片roundTime。

遍历进程组的时候,每运行一个进程,就把curTime += roundTime。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、课程设计目的进程操作系统课程设计,主要是在学习操作系统课程设计的基础上,完成操作系统各部分的要求,对操作系统的一些功能进行一次模拟。

通过本次的课程设计,提高运用操作系统知识解决实际问题的能力,锻炼实际的编程能力,还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。

二、课程设计内容与要求1.设计内容在多道程序和多任务系统中,系统内同时处于就绪状态的进程可能有若干个,也就是能运行的进程数大于处理机的个数,为了是系统中的进程有条不紊的工作,必须选用某种调度策略,在一定的时机选择一个进程占用处理机。

要求设计一个模拟处理机调度算法,以巩固和加深处理机调度的概念。

2.设计要求①在多道、单处理机条件下进行模拟。

②进程调度算法包括:时间片轮转算法、先来先服务算法、短作业优先算法、静态优先权优先调度算法、高响应比调度算法。

③每一个进程有一个PCB,其内容可以根据具体情况设定。

④进程数、进入内存时间、要求服务时间、作业大小、优先级等均可以在界面上设定。

⑤可读取样例数据(要求存放在外部文件中)进行进程数、进入内存时间、时间片长度、作业大小、进程优先级的初始化操作。

⑥可以在运行中显示各进程的状态。

⑦采用可视化界面,可以在进程调度过程中随时暂停调度,查看当前进程的状态及相应的阻塞队列。

⑧有性能比较功能,可比较同一组数据在不同调度算法下的平均周转时间。

⑨具有一定的数据容错性。

三、系统分析与设计1.系统分析本系统是通用处理机调度程序,需要实现的功能有:用户可以输入进程信息,进行调度算法的演示;用户还可以从本系统的文件中读取数据,进行调度算法的演示;在演示的过程中,可以随时暂停、继续或者重新开始执行,查看相应的阻塞队列;在这个程序中,还可以比较同一组数据在不同调度算法下的平均周转时间。

系统对于用户输入的信息具有一定的检错和提示错误的功能,帮助用户更好的使用本程序,进行通用处理机调度的演示程序。

对于系统的逻辑结构,系统的功能与性能具体分析如下:(1)信息方面本程序所处理的信息的来源有两种,磁盘上存储进程信息的外部文件、用户通过界面输入的进程信息。

每一个进程的信息,包括进程的名称、进入时间、要求服务时间、作业大小、优先级。

(2)行为方面在添加进程的窗体中,根据用户输入的进程数目,依次读入到文件中,进行存储。

在录入信息完成以后,添加窗体向演示窗体传递保存的文件名称。

演示窗体中,可以单击开始演示按钮观看调度的演示顺序,单击查看阻塞队列按钮查看当前时间的阻塞队列,以及单击查看平均周转时间的按钮来查看数据在用户选择的算法下的平均周转时间。

(3)表示方面本演示程序包括三个界面,打开程序显示的主窗体、添加进程的窗体、演示窗体。

在主窗体中,介绍本程序的主要功能,以及显示用户可以操作的功能按钮;添加进程的窗体中,可以允许用户填写输入进程的数目、保存的文件名称、每个进程的详细信息;演示窗体中,根据时间显示进程的执行顺序以及进程处于的状态(阻塞、执行、完成)。

2.系统设计2.1、模块设计:(1)主程序流程:(2)模块之间的关系:(3)界面之间的关系:2.2、数据结构说明:(1)Process类将每一个进程的信息抽象成一个进程的类用来存储进程的信息,其中包括进程的全部的PCB信息。

(2)对于不同的调度算法,在进行选择的时候,通过枚举类型来实现2.3、算法流程图:(1)主程序函数过程的调用关系图(2)演示(RunProc函数)的主要绘图代码:四、系统测试与调试分析1.系统测试:2.调试分析:在程序的调试过程中,出现问题是编程中常见的事情,自己能够调试程序并找出原因是解决问题的关键。

本程序在编写的过程中,遇到了如下一些问题:(1)在Process类的使用过程中出现了空值异常。

解决办法,编写构造函数,在声明的时候给类赋初始值,从而避免了空值调用其中的属性或方法而产生的异常。

(2)在调试RR算法求取执行序列的时候出现了问题,不能得到正常的执行序列。

原因:第一次编写的时候对时间片的考虑不全面,只考虑了1和2 的情况,没有考虑更大的情况,通过修改代码,改正了错误。

通过以上的调试过程,程序正确运行,回顾以前对系统的设计方面的内容,发现,一开始的设计存在考虑不周全的地方,比如标志变量Flag,是在编程的过程中需要才加入的,这样并不影响程序的正确性。

通过这个说明,设计不可能一开始就是完美的,要在编程的过程中不断的完善和改进。

五、用户手册1.使用平台:Microsoft Visual Studio 2008下载网址:/html/4615.html2.需要安装从给出的网址中下载软件,运行安装文件,根据提示进行安装即可。

3.使用说明:(1)使用前的准备工作将文件拷贝到D:\ApplicationProjects\C#Projects\WinformProjects目录下,如果没有此目录的话,建立相应的目录结构。

(2)双击\通用处理机调度演示程序\通用处理机调度演示程序\bin\Debug 下的通用处理机调度演示程序.exe文件,运行本程序。

界面如图1。

图1:通用处理机调度演示程序界面(3)在界面中有三个选项,可以选择样例数据演示、录入调度数据以及推出本程序。

单击则执行相应的操作。

(4)当选择样例数据演示时,出现以下图2界面图2:演示界面(5)在下拉列表中选择采用的调度算法,当选择时间片轮转调度算法时,会出现以下内容,如图3,需要输入时间片的大小;图3:时间片的录入(6)选择好一种调度算法后,便点击开始演示按钮进行演示,如图4图4:进行演示的界面(7)在演示的过程中,可以随时暂停演示以及继续演示的操作,只需要点击相应的按钮即可。

(8)在演示的过程中,可以查看就绪队列。

如图5图5:查看阻塞队列的情况(9)执行完毕后,显示如图6图6:执行完毕(10)查看平均周转时间,显示如图7图7:查看平均周转时间(11)当选择录入调度数据时,显示如下界面,如图8图8:录入调度数据界面(12)当数据录入完毕,点击提交按钮时,会打开演示窗体,进行演示的操作,具体演示操作参看以前步骤即可。

(13)当点击退出本程序的按钮时,便退出了通用处理机调度的演示程序。

六、程序清单(1)绘制演示区域的主要代码:#region演示的主要绘图代码///主要实现的功能:///根据数据的多少来绘制左面和下面的分隔///根据传入的参数,绘制块///函数功能实现做成函数,传入参数privatevoid RunProc(object sender, EventArgs e){timer1.Enabled = false;#region初始化变量--获取执行序列(单位时间格式)-x、y坐标轴的长度Process[] p = getProcessFromFile(fileName);#region控制时间片的输入,不输入时,提示错误if (txt_timeSize.Visible == true&& txt_timeSize.Text == ""){MessageBox.Show("请输入时间片大小!");return;}#endregion//根据以上信息,生成执行顺序int[] exeS = getExeScheduling(cbo_itemList.SelectedIndex, p);l = exeS.Length;int x_length = Jiuhong1989.Mc.Winform.ShowUsed.Drawing.getX(exeS);int y_length = Jiuhong1989.Mc.Winform.ShowUsed.Drawing.getY(exeS);#endregion#region状态为running的时候,执行的代码,实现动态的绘制图形if (state == RunState.running)//状态为running的时候才执行这段代码{Jiuhong1989.Mc.Winform.ShowUsed.Drawing.drawImge(exeS[downflag++], myImage, (downflag - 1), x_length, y_length);Graphics g = Graphics.FromImage(myImage);int y = 420 - (exeS[downflag - 1] + 1) * y_length + y_length / 2;//绘制当前执行的标志---执行中(蓝色)Rectangle rect = new Rectangle(680, y, 25, 15);System.Drawing.Drawing2D.LinearGradientBrush lBrush = new System.Drawing.Drawing2D.LinearGradientBrush(rect, System.Drawing.Color.Blue, Color.Blue, System.Drawing.Drawing2D.LinearGradientMode.Horizontal);g.FillRectangle(lBrush, rect);this.BackgroundImage = myImage;this.Refresh();//实现窗体刷新,否则,延迟显示if (totalServiceTime[exeS[downflag - 1]] > 0){totalServiceTime[exeS[downflag - 1]] =totalServiceTime[exeS[downflag - 1]] - 1;}#region找到阻塞队列,将其中的元素对应的设置成阻塞---(红色) Process[] b = getBlock(exeS);bool tips = false;if (b != null){for (int i = 0; i < b.Length; i++){if (b[i] != null){tips = true;break;}}}if (tips){for (int i = 0; i < b.Length; i++){if (b[i] != null){int y_values = 420 -(b[i].PrivatePcb + 1) * y_length+y_length / 2;Rectangle r = new Rectangle(680, y_values, 25, 15);System.Drawing.Drawing2D.LinearGradientBrush lbrush = new System.Drawing.Drawing2D.LinearGradientBrush(r, System.Drawing.Color.Red, Color.Red, System.Drawing.Drawing2D.LinearGradientMode.Horizontal);g.FillRectangle(lbrush, r);this.BackgroundImage = myImage;this.Refresh();//实现窗体刷新,否则,延迟显示}}}#endregion#region绘制y轴上的坐标,应该根据到达的时间来绘制Process[] t = getProcessFromFile(fileName);for (int i = 0; i < t.Length; i++){int yy = 420 - (i + 1) * y_length + y_length / 2;g.DrawString(t[i].PCB, new Font("宋体",12),Brushes.Red,new PointF(5, yy));}#endregion#region绘制完成标志---(绿色)if (totalServiceTime[exeS[downflag - 1]] == 0){Rectangle rec = new Rectangle(680, y, 25, 15);System.Drawing.Drawing2D.LinearGradientBrush lB = new System.Drawing.Drawing2D.LinearGradientBrush(rec, System.Drawing.Color.Green, Color.Green, System.Drawing.Drawing2D.LinearGradientMode.Horizontal);g.FillRectangle(lB, rec);this.BackgroundImage = myImage;this.Refresh();//实现窗体刷新,否则,延迟显示}#endregion#region绘制x轴坐标for (int i = 0; i <= 630 / x_length; i++){//绘制x坐标的数值g.DrawString(Convert.ToString(i), new Font("宋体", 12), Brushes.Red, new PointF(38 + i * x_length, 425));//绘制坐标的分隔线g.DrawLine(new Pen(Brushes.Red), new PointF(50 + i * x_length, 420), new PointF(50 + i * x_length, 425));}#endregionthis.BackgroundImage = myImage;this.Refresh();//实现窗体刷新,否则,延迟显示if (downflag >= exeS.Length){state = RunState.stop;MessageBox.Show("执行完毕");}System.Threading.Thread.Sleep(2000);//暂停一段时间,方便查看和暂停timer1.Enabled = true;}#endregion}#endregion(2)获取执行顺序的代码///根据传入的排序类型,将Process按照指定的类型排序publicstatic Process.Process[] getRank(Process.Process[] process,rankType type) {#region先来先服务调度算法,返回执行顺序if (type == rankType.EnteringTime)//完成{//根据进入内存时间进行排序(从小到大顺序)Process.Process temp;for (int i = 0; i < process.Length-1; i++){for (int j = i+1; j < process.Length;j++ ){if(process[i].EnteringTime > process[j].EnteringTime){temp = process[i];process[i] = process[j];process[j] = temp;}}}}#endregion#region静态优先权优先调度算法,返回执行顺序elseif(type == rankType.Priority){//静态优先权优先调度算法//根据进入内存时间和优先级类判断int num = 0;//下标//首先按照进入时间排序,然后根据优先级对排序进行调整Process.Process temp;//交换时候的中间变量for (int i = 0; i < process.Length - 1; i++){for (int j = i + 1; j < process.Length; j++){if (process[i].EnteringTime > process[j].EnteringTime){temp = process[i];process[i] = process[j];process[j] = temp;}}}//根据优先级修改顺序//在前一个程序的执行时间内,进入的进程,将这些进程按照优先权进行排序for (int i = 0; i < process.Length;i++ ){//获取前面一段的要求服务总时间int totalServiceTime = 0;for (int x = 0; x <= i;x++ ){totalServiceTime = totalServiceTime +Convert.ToInt32(process[x].ServiceTime);}//找到要处理的进程数组,即在前一个进程处理时间内到达的进程Process.Process[] front = newJiuhong1989.Mc.Winform.Process.Process[process.Length];//注意空值for (int j = i+1; j < process.Length;j++ ){if (Convert.ToInt32(process[j].EnteringTime) < totalServiceTime){front[j] = process[j];}}//将front中的非空数据,按优先级排序Process.Process m;for (int ii = 0; ii < front.Length-1;ii++ ){for (int j = ii + 1; j < front.Length;j++ )if (front[ii] != null&& front[j] != null){if (front[ii].Priority < front[j].Priority)//将优先权大的排在前面 {m = front[ii];front[ii] = front[j];front[j] = m;}}}}//将front中的非空数据,覆盖process中的相应位置的数据for (int a = 0; a < front.Length;a++ ){if (front[a] != null){process[a] = front[a];}}}}#endregion#region短作业优先调度算法,返回执行顺序elseif(type == rankType.JobSize){//这里实现短作业优先调度算法,方法类似静态优先权的调度算法//具体的实现代码如下int num = 0;//下标//首先按照进入时间排序,然后根据优先级对排序进行调整#region首先按照进入时间排序Process.Process temp;//交换时候的中间变量for (int i = 0; i < process.Length - 1; i++){for (int j = i + 1; j < process.Length; j++){if (process[i].EnteringTime > process[j].EnteringTime){temp = process[i];process[i] = process[j];process[j] = temp;}}}//根据进程的作业大小修改顺序//在前一个程序的执行时间内,进入的进程,将这些进程按照作业大小进行排序//注意:对于进入时间相同的,按照作业大小,之后是私有的pcbfor (int i = 0; i < process.Length; i++){//获取前面一段的要求服务总时间int totalServiceTime = 0;for (int x = 0; x <= i; x++){totalServiceTime = totalServiceTime +Convert.ToInt32(process[x].ServiceTime);}//找到要处理的进程数组,即在前一个进程处理时间内到达的进程Process.Process[] front = newJiuhong1989.Mc.Winform.Process.Process[process.Length];//注意空值for (int j = i + 1; j < process.Length; j++){if (Convert.ToInt32(process[j].EnteringTime) < totalServiceTime){front[j] = process[j];}}//将front中的非空数据,按优先级排序Process.Process m;for (int ii = 0; ii < front.Length - 1; ii++){for (int j = ii + 1; j < front.Length; j++){//if (front[ii] != null&& front[j] != null){if (front[ii].ServiceTime > front[j].ServiceTime)//将作业大的排在后面,实现短作业优先{m = front[ii];front[ii] = front[j];front[j] = m;}}}}//将front中的非空数据,覆盖process中的相应位置的数据for (int a = 0; a < front.Length; a++){if (front[a] != null){process[a] = front[a];}}}}#endregion#region高响应比调度算法,返回执行顺序/*具体过程:* 按照作业的进入时间进行排序* 每次作业执行完之后,就计算在总的运行时间内,到达的并且没有执行的进程的响应比* 选择一个响应比最大的插入执行队列中去,循环,直至传入进程参数的末尾* 具体的过程见下面分支的代码*/elseif(type == rankType.HighResponseRatio){//高响应比的情况int num = 0;//下标//首先按照进入时间排序Process.Process temp;//交换时候的中间变量for (int i = 0; i < process.Length - 1; i++){for (int j = i + 1; j < process.Length; j++){if (process[i].EnteringTime > process[j].EnteringTime){temp = process[i];process[i] = process[j];process[j] = temp;}}}//根据进程的响应比修改顺序//在前一个程序的执行时间内,进入的进程,将这些进程按照响应比进行排序for (int i = 0; i < process.Length; i++){//获取前面一段的要求服务总时间int totalServiceTime = 0;for (int x = 0; x <= i; x++){totalServiceTime = totalServiceTime + Convert.ToInt32(process[x].ServiceTime);}//找到要处理的进程数组,即在前一个进程处理时间内到达的进程Process.Process[] front = newJiuhong1989.Mc.Winform.Process.Process[process.Length];//注意空值for (int j = i + 1; j < process.Length; j++){if (Convert.ToInt32(process[j].EnteringTime) < totalServiceTime) {front[j] = process[j];}}//将front中的非空数据,按响应比排序Process.Process m;for (int ii = 0; ii < front.Length - 1; ii++){for (int j = ii + 1; j < front.Length; j++){if (front[ii] != null&& front[j] != null){if (getHighResponseRatio(front[ii],totalServiceTime)< getHighResponseRatio(front[j],totalServiceTime)){m = front[ii];front[ii] = front[j];front[j] = m;}}}}//将front中的非空数据,覆盖process中的相应位置的数据for (int a = 0; a < front.Length; a++){if (front[a] != null){process[a] = front[a];}}}}#endregionreturn process;}(3)时间片轮转调度算法执行顺序的获取代码///时间片轮转算法的实现函数///主要的功能是返回执行顺序///这个的执行顺序是间断的publicstatic Process.Process[] getRank(Process.Process[] process, int timeSize) {#region时间片轮转调度算法获取进程执行顺序的执行过程简单介绍/* 将输入的进程数组中的数据按照到达时间从小到大的顺序进行排序* 外围循环,总的服务时间内,每次都遍历整个Process[],对阻塞队列进行赋值操作* 判断的条件是外围的到达时间* 选出到达时间在规定时间之内的进程,存入阻塞队列* 放入阻塞数组后,以后每次执行前都要查看,若有元素,就执行阻塞数组中的,若没有,则执行外围的循环操作*/#endregion#region首先按照进入时间排序,然后根据优先级对排序进行调整Process.Process temp;//交换时候的中间变量for (int i = 0; i < process.Length - 1; i++){for (int j = i + 1; j < process.Length; j++){if (process[i].EnteringTime > process[j].EnteringTime){temp = process[i];process[i] = process[j];process[j] = temp;}}}#endregion#region获取总的要求服务时间totalServiceTimeint totalServiceTime = 0;for (int x = 0; x < process.Length; x++){totalServiceTime = totalServiceTime +Convert.ToInt32(process[x].ServiceTime);}#endregion#region参数设置//数组的大小 = 要求服务的总时间/时间片int size = totalServiceTime / timeSize + 1;//返回数组的大小//声明一个Process数组,作为返回值int randSize = 0;Process.Process[] rank = newJiuhong1989.Mc.Winform.Process.Process[size+20];//这个数组只是用来存放执行顺序!!!//声明一个Process数组作为阻塞队列,存放待执行的进程信息(要求服务时间随着执行次数,减小相应的数值)Process.Process[] block = newJiuhong1989.Mc.Winform.Process.Process[size+20];//每次都是从这个Process数组中取数据,进行操作//设置一个变量,标识执行的总时间int exeTime = 0;bool isInHourPiece = false;int exeTimeOfProcess = 0;#endregion#region根据总的服务时间进行循环,每执行一个单位的时间就检查一次for (int i = 0; i <= totalServiceTime; i++){//以下是获取返回序列的主要操作代码:#region阻塞队列中没有待执行的程序,不需要对其进行操作if (block[0] == null){//Do Nothing}#endregion#region阻塞队列中有待执行的程序,需要对其进行操作else{//rank[randSize++] = block[0];//执行队列赋值#region服务时间在时间片之内的情况if (block[0].ServiceTime <= timeSize){isInHourPiece = true;exeTimeOfProcess =Convert.ToInt32(block[0].ServiceTime);}#endregion#region服务时间超过了时间片的大小else{isInHourPiece = false;exeTimeOfProcess = timeSize;}#endregion#region设置返回数组及阻塞数组if (isInHourPiece){block[0].ServiceTime = 0;rank[randSize++] = block[0];//执行队列赋值block[0] = null;isInHourPiece = false;}else{block[0].ServiceTime = block[0].ServiceTime - timeSize; rank[randSize++] = block[0];//执行队列赋值}#endregion}#endregion//将exeTime的数值增加exeTime = exeTime + exeTimeOfProcess;#region Process类型的数组,用来存放在时间片轮转执行过程中 "新来的" 需要阻塞进程 Process.Process[] front = newJiuhong1989.Mc.Winform.Process.Process[process.Length];for (int j = 0; j < process.Length;j++ ){//查找在执行时间内到达的进程if(Convert.ToInt32(process[j].EnteringTime) <= exeTime){if ( process[j].Flag == false) {front[j] = process[j];process[j].Flag = true;//设置标志,进入的就不用重新进入了}}}#endregion//将查找到的非空元素放入block中,并将首位的移动到最后#region执行步骤/** 实现的具体步骤如下:* 如果阻塞数组是空的话:直接赋值给前面的0,1,2....* 如果阻塞数组是非空的话* :将第一个元素取出,保存在中间变量中* :将其余的一次前移* :队尾插入新到的* :将队首的加在最后*/#endregion#region阻塞数组是空//判断空值bool isNull = true;for (int f = 0; f < block.Length; f++){if(block[f]!=null){isNull = false;break;}}if (isNull)//如果是空{int number = 0;for (int n = 0; n < front.Length; n++){if (front[n] != null){block[number++] = front[n];}}}#endregion#region阻塞数组非空的情况:else{#region将第一个元素取出,保存在中间变量中Process.Process mid = newJiuhong1989.Mc.Winform.Process.Process();mid = block[0];#endregion#region将其余的一次前移for (int g = 0; g < block.Length - 1; g++){block[g] = block[g + 1];//}#endregion#region将查找到的放入阻塞数组中去,从第一个null的地方开始存放for (int h = 0; h < block.Length; h++){if (block[h] == null){for (int k = 0; k < front.Length; k++){if (front[k] != null){block[h] = front[k];front[k] = null;break;}}}}#endregion#region将队首的加在最后for (int p = 0; p < block.Length; p++){if (block[p] == null){block[p] = mid;break;}}#endregion}#endregion}#endregionreturn rank;}(4)阻塞队列的实现函数是根据执行顺序来获取的,实现起来相对简单,这里就不再罗列代码,详细代码,参见源程序代码即可。

相关文档
最新文档