资源描述
课程名称: 操作系统B 实验项目: 操作系统实验 实验地点: 实验楼209 专业班级: 软件 学生姓名: 学号: 指导教师: 方昀 2015 年 11 月 30目 录实验一 几种操作系统的界面1一、目的和要求1二、内容1实验二 进程调度程序设计2一、目的和要求2二、示例2实验三 存储管理程序设计9一、目的和要求9二、提示9实验一 几种操作系统的界面一、目的和要求(一) 目的本实验的目的是使学生熟悉12种操作系统的界面,在熟练使用机器的基础上,能了解各种操作命令和系统调用在系统中的大致工作过程。也就是通过操作系统的外部特征,逐步深入到操作系统的内部实质内容中去。(二) 要求1. 能熟练的在12种操作系统的环境下工作,学会使用各种命令,熟悉系统提供的各种功能,主动而有效地使用计算机。2. 熟悉系统实用程序的调用方法和各种系统调用模块的功能和作用二、内容在某种操作系统的环境下建立、修改、运行、打印源程序和结果,最后撤消一个完整的程序。提示:可按下述步骤进行1 编写一个完整的源程序,通过编辑命令送入机器,建立源程序文件;2 编译该源文件,建立相应的目标文件;3 编译有错时,再用编辑命令修改源文件,消除全部词法和语法错误;4 连接目标文件,形成可执行文件;5 执行该文件,得到结果;6 打印输出源程序和运行结果;7 撤消本次实验中形成的所有文件。三、实验步骤及程序流程图1)Dos命令行。1. 按住Windows键+R输入notepad回车调出记事本。2. 编辑一个java程序选择另存为d:。3. 按住Windows键+R输入cmd回车。4. 进入Dos界面键入d:。5. 输入dir查看java文件,使用javac命令进行编辑四、程序清单(据情况而定)class demo public static void main(String args) System.out.print(这是一个java例子); 五、讨论、心得本次实验是在Windows10系统下进行的,通过对一个Java小程序的编译连接熟悉对Win10的操作以及DOS命令的使用。试验中使用到的DOS工具: 查看目录:dir 编辑:javac 通过本次实验,进一步熟悉了对操作系统尤其是DOS 命令的使用,初步了解了部分操作命令和系统调用在系统中的大致工作过程,通过实践也加深了对老师课堂一些所讲知识的理解。实验二 进程调度程序设计一、目的和要求(一) 目的进程是操作系统最重要的概念之一,进程调度是操作系统的主要内容,本实验要求学生独立地用高级语言编写一个进程调度程序,调度算法可任意选择或自行设计,本实验可使学生加深对进程调度和各种调度算法的理解。(二) 要求1 设计一个有几个进程并发执行的进程调度程序,每个进程由一个进程控制块(PCB)表示,进程控制块通常应包括下述信息:进程名,进程优先数,进程需要运行的时间,占用CPU的时间以及进程的状态等,且可按照调度算法的不同而增删。2 调度程序应包含23种不同的调度算法,运行时可以任选一种,以利于各种方法的分析和比较。3 系统应能显示或打印各进程状态和参数的变化情况,便于观察。二、示例1 题目 本程序可选用优先数法或简单轮转法对五个进程进行调度。每个进程处于运行R(run)、就绪W(wait)和完成F(finish)三种状态之一,并假定起始状态都是就绪状态W。为了便于处理,程序中进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。进程控制块结构如表2-1所示: 表2-1 PCB 进程标识符 链指针 优先数/轮转时间片数 占用CPU时间片数 进程所需时间片数 进程状态进程控制块链结构如图2-1所示: RUN HEAD TAIL 图2-1 进程控制块链结构其中:RUN当前运行进程指针;HEAD进程就绪链链首指针;TAIL进程就绪链链尾指针。2. 算法与框图 程序框图如图2-2所示。图2-2 进程调度框图 (1)优先数法。 进程就绪链按优先数大小从大到小排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3。理由是该进程如果在一个时间片中完成不了,优先级应降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续运行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。(2)简单轮转法。 进程就绪链按各进程进入的先后次序排列,链首进程首先投入运行。进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相应于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。 三、代码:#include #include #define furthest 5 struct process /*PCB STRUCTURE*/int id;int priority;int cputime;int alltime;char state;int next;prochainfurthest - 1;int procnum;int rand();int algo;int run, head, tail, j;void print();void insert(int q);void insert2();void timesch();void init();void prisch(); int main() /*MAIN PROGRAM*/agan: printf(type the algorithm is (1:RR,2:PRIO):);scanf(%d, &algo);if (algo = 2)printf(output of priority.n);init();prisch();elseif (algo = 1)printf(output of round robin.n);init();timesch();elseprintf(try again,pleasen);goto agan;for (j = 1; j = 40; j+)printf(=);printf(nn);for (j = 1; j = 40; j+)printf(=);printf(nn);printf(system finishedn);getchar();void print() /*PRINT THE RUNNING PROCESS,WAITING QUEUE AND PCB SEQUENCE LIST*/int k, p;for (k = 1; k = 40; k+)printf(=);printf(nrunning proc. );printf(waiting queue.);printf(n %d , prochainrun.id);p = head;while (p != 0)printf(%5d, p);p = prochainp.next;printf(n);for (k = 1; k = 40; k+)printf(=);printf(n);printf( id );for (k = 1; kfurthest + 1; k+)printf(%5d, prochaink.id);printf(n);printf(priority );for (k = 1; kfurthest + 1; k+)printf(%5d, prochaink.priority);printf(n);printf(cputime );for (k = 1; kfurthest + 1; k+)printf(%5d, prochaink.cputime);printf(n);printf(alltime );for (k = 1; kfurthest + 1; k+)printf(%5d, prochaink.alltime);printf(n);printf(state );for (k = 1; kfurthest + 1; k+)printf(%5c, prochaink.state);printf(n);printf(next );for (k = 1; kfurthest + 1; k+)printf(%5d, prochaink.next);printf(n);void insert(int q) /*INSERT A PROCESS*/int p, s;p = head;s = prochainhead.next;while (prochainq.priorityprochains.priority) & (s != 0)p = s;s = prochains.next;prochainp.next = q;prochainq.next = s;void insert2() /*PUT A PROCESS ONTO THE TAIL OF THE QUEUE*/prochaintail.next = run;tail = run;prochainrun.next = 0;void init() /*CREATE A WAITING QUEUE*/int i;head = 0;if (algo = 2)for (i = 1; ifurthest + 1; i+)prochaini.id = i;prochaini.priority = (rand() + 11) % 41;prochaini.cputime = 0;prochaini.alltime = (rand() + 1) % 7;prochaini.state = W;prochaini.next = 0;if (prochaini.priorityprochainhead.priority) & (head != 0)insert(prochaini.id);elseprochaini.next = head;head = prochaini.id;elsefor (i = 1; ifurthest + 1; i+)prochaini.id = i;prochaini.priority = (rand() + 1) % 3 + 1;prochaini.cputime = 0;prochaini.alltime = (rand() + 1) % 7;prochaini.state = W;prochaini.next = (i + 1) % (furthest + 1);head = 1;tail = furthest;prochainfurthest.next = 0;run = head;prochainrun.state = R;head = prochainhead.next;prochainrun.next = 0;print();void prisch() /*THE PROCESS WITH PRIO ALGORITHM*/while (run != 0)prochainrun.cputime += 1;prochainrun.priority -= 3;prochainrun.alltime -= 1;if (prochainrun.alltime = 0)prochainrun.state = F;prochainrun.next = 0;if (head != 0)run = head;prochainrun.state = R;head = prochainhead.next;elseprochain0.id = prochainrun.id;run = 0;elseif (prochainrun.priority prochainhead.priority) & (head != 0)prochainrun.state = W;insert(run);run = head;prochainrun.state = R;head = prochainhead.next;print();void timesch() /*THE PROCESS WITH RR ALRORITHM*/while (run != 0)prochainrun.alltime -= 1;prochainrun.cputime += 1;if (prochainrun.alltime = 0)prochainrun.state = F;prochainrun.next = 0;if (head != 0)run = head;prochainrun.state = R;head = prochainhead.next;elseprochain0.id = prochainrun.id;run = 0;elseif (prochainrun.cputime = prochainrun.priority) & (head != 0)prochainrun.state = W;prochainrun.cputime = 0;insert2();run = head;prochainrun.state = R;head = prochainhead.next;print();四、结果:五、感想: 本次试验的目的在于加深对进程调度和各种调度算法的理解,故通过对优先数法和简单轮转法编辑程序实际运行来加深对这两种方法的理解。 对于简单轮转法,既将全部的进程按照进入的先后顺序排成一个就绪队列,设置每隔一段时间后将CPU分配给队列中新的队首进程,这样就可以保证就绪队列中的所有进程在确定的时间段内都能获得一个时间片的处理机时间。 而对于优先数法,本次试验中使用了动态优先数对进程进行排序,即就绪队列按优先数从大到小进行排列,而各进程的优先数随着进程的推进而改变,以达到获取更好的调度性能的目的。简单轮转法有效的保证了队列中的所有进程都能分配到处理机,而优先数法则可防止一个长作业长期的垄断处理机。通过本次实验对试验中所涉及的两种算法的理解进一步加深,有效复习了课堂上所讲到的相关知识。实验三 存储管理程序设计一、目的和要求(一) 目的存储管理的主要功能之一是合理地分配主存空间。请求页式管理是一种常用的虚拟存储管理技术。本实验的目的是通过请求页式存储管理中页面置换算法的模拟设计,来了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。(二) 要求模拟页式虚拟存储管理中硬件的地址转换和缺页中断的处理过程,并用先进先出调度算法(FIFO)处理缺页中断。二、提示(1) 为了装入一个页面而必须调出一页时,如果被选中调出的页面在执行中没有修改过,则不必把该页重新写到磁盘上(因磁盘上已有副本)。因此,在页表中可以增加是否修改过的标志,当执行“存”指令、“写”指令时把对应页的修改标志置成“1”,表示该页修改过,否则为“0”,表示该页未修改过。页表格式如表3-1所示。表3-1 页表格式 页 号 标 志 主存块号 修改标志 磁盘上的位置(2) 设计一个地址转换程序来模拟硬件的地址转换和缺页中断处理过程。当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可用输出转换后的绝对地址来表示一条指令已完成。当访问的页不在主存时则输出“*该页页号”来表示硬件产生了一次缺页中断。模拟地址转换的程序流程如图3-1所示。(3) 编制一个FIFO页面调度程序。FIFO页面调度算法总是先调出作业中最先进入主存的那一页,因此,可以用一个数组来构成页号队列。数组中每个元素是该作业已在主存的页面号,假定分配给作业的主存块数为m,且该作业开始的m页已装入主存,则数组可由m个元素组成:P0,P1,Pm-1它们的初值为P0=0,P1=1,Pm-1= m-1用一指针k指示当要装入新页时应调出的页在数组的位置,k的初值为“0”。图3-1 地址转换和FIFO页面调度流程当产生缺页中断后,操作系统总是选择Pk所指出的页面调出,然后执行Pk=要装入的新页页号k=(k+1)mod m在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入的过程。模拟程序的流程见图3-1。(1) 假定主存的每块长度为1024个字节,现有一个共7页的作业,其副本已在磁盘上。系统为该作业分配了4块主存块,且该作业的第0页至第3页已经装入主存,其余3页尚未装入主存,该作业的页表见表3-2所示。表3-2 作业的页表 页号 标志 主存块号 修改标志 在磁盘上的位置 0 1 5 0 011 1 1 8 0 012 2 1 9 0 013 3 1 1 0 021 4 0 0 022 5 0 0 023 6 0 0 121如果该作业依次执行的指令序列如表3-3所示。表3-3 作业依次执行的指令序列 操作 页号 页内地址 操作 页号 页内地址 + 0 070 移位 4 053 + 1 050 + 5 023 2 015 存 1 037 存 3 021 取 2 078 取 0 056 + 4 001 - 6 040 存 6 084依次执行上述的指令序列来调试你所设计的程序(仅模拟指令的执行,不必考虑指令序列中具体操作的执行)(2) 为了检查程序的正确性,可自行确定若干组指令序列,运行设计的程序,核对执行结果。三、代码:#include #include #include using namespace std;struct pageTable/定义页表int address;/地址int page;/页号int block;/块号struct pageTable *next;typedef struct pageTable PAGETABLE;PAGETABLE *pt;const int first_memory = 1000;/内存首地址int work320;/作业int index, offset;/index是作业的页号,offset为页内偏移地址PAGETABLE*oldPtr;/minPtr指向驻留时间最久的页int count1;/记数器,用于记录发生的缺页数bool is_LRU = false;/是否是LRU算法void init();void insertPage();void pushback_Page(PAGETABLE *, PAGETABLE *);void print(PAGETABLE *);void run(int);void find_FIFO();void find_LRU();void main(void)int i = 0;while (1)cout nPlease select a number(1,2,0) endl;cout 1-先进先出算法(FIFO) endl;cout 2-最久未使用算法(LRU) endl;cout 0-程序结束 i;if (i = 1)cout nThis is a example for FIFO: endl;is_LRU = false;init();/构造页表和内存else if (i = 2)cout nThis is a example for LRU: next = NULL;for (int i = 0; inext;/初始化最久的页面cout 页表初始状态为: endl;print(pt);for (int k = 0; k320; k+)/初始化作业workk = k;for (int f = 0; f53; f+)/作业运行int m, m1, m2;m = rand() % 320;if (m = 319)m = 318;run(m);print(pt);run(m + 1);print(pt);if (m = 0)m1 = 0;elsem1 = rand() % m;run(m1);print(pt);run(m1 + 1);print(pt);m2 = rand() % (320 - m) + m - 1;if (m20)m2 = 318;if (m2 = 319)m2 = 318;run(m2);print(pt);run(m2 + 1);print(pt);rate = (double)count / 318 * 100;cout nn 缺页率为: rate % address = id;newPage-page = -1;newPage-block = blockId;newPage-next = NULL;pushback_Page(pt, newPage);elsecout 没有内存足够的空间为页表分配! next;while (current != NULL)previous = current;current = current-next;previous-next = item;void print(PAGETABLE *ptr)PAGETABLE *temp;temp = ptr-next;cout 页号 块号 endl;while (temp != NULL)cout page block next;void run(int num)int universal;PAGETABLE *previous, *current;index = worknum / 10;/程序所在的页号offset = worknum % 10;/页内的位移量previous = pt;current = previous-next;while (current != NULL & current-page != index)previous = current;current = current-next;if (current = NULL)cout n作业 num 没有在内存,发生缺页中断 block) * 10 + offset;cout n作业 num 所在内存的物理地址为 universal next = NULL)universal = first_memory + (current-block) * 10 + offset;cout n作业 num 所在内存的物理地址为 universal next = current-next;ptr = pt-next;while (ptr-next != NULL)ptr = ptr-next;ptr-next = temp;temp-next = NULL;universal = first_memory + (temp-block) * 10 + offset;cout n作业 num 所在内存的物理地址为 universal next;if (oldPtr = NULL)oldPtr = pt-next;while (pos != NULL & pos-page != -1)pos = pos-next;if (pos = NULL)/出现缺页中断cout *页面开始置换* page = index;universal = first_memory + (oldPtr-block) * 10 + offset;cout 置换后作业在内存的物理地址为 universal next;else/页面还未装完pos-page = index;universal = first_memory + (pos-block) * 10 + offset;cout 作业在内存的物理地址为 universal next;while (pos != NULL & pos-page != -1)pos = pos-next;if (pos = NULL)/出现缺页中断cout *页面开始置换* next;temp-page = index;universal = first_memory + (temp-block) * 10 + offset;cout 置换后作业在内存的物理地址为 universal page = index;universal = first_memory + (pos-block) * 10 + offset;cout 作业在内存的物理地址为 universal endl;四、结果:五、心得本次试验的目的是通过请求页式存储管理中页面置换算法的模拟设计,来了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。试验中主要使用了FIFO算法,即总是先淘汰最先进入内存的页面(驻留最久的页面),实现时只需要把一个进程也调入内存的页面按先后次序链接成一个队列,并设置一个指针,总是指向最老的页面。FIFO的主要的缺点是没有考虑到有的页面会经常被访问,因此并没有办法保证这种页面能够保留在内存中,可能使得利用率较低。通过本次试验加深了对相应算法的理解,巩固了相关的知识和使用的方法。
展开阅读全文