实验一、进程调度实验报告
广东技术师范学院实验报告
计算机科学学
院
姓名: 学院: 实验地点: 预习情况 实验名称: 实验一、进程调度实验
一、实验目的
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解
二、实验类别
综合性实验。综合高级语言编程、进程调度模型、进程调度算法及数据结构等多方面的知识
三、实验内容和步骤
1.编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对五个进程进行调度。
“最高优先数优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。
静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。
动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定原则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1。或者,进程等待的时间超过某一时限时增加其优先数的值,等等
该题根据老师给的代码用Visual C++运行,结果以及分析如下:
计算机科学与专业:班级: 成绩:
技术(师范)
学号: 组别: 组员:
实验日期:
指导教师签名:
操作情况 考勤情况 数据处理情况
结果分析:根据上述输入的三个进程的信息可以得到:优先级最高的是进程cc最先调度进程cc的状态为运行态,需要执行的时间为10当前就绪队列状态为:进程aa先级比较高,处于就绪队列前面,而进程bb先级是三者中最低的,所以处于就绪队列的最后。而此时这两个进程的状态都为就绪态。
结果分析:当进程cc了一个时间片之后而它已占用 CPU时间已达到所需要的运行时间,则将它的优先级减1之后,再将三个进程按优先级的大小排列,从中选择优先级大的进程进入运行状态,则该次进入运行态的是进程aa
按照这种方式一直运行下去:
直到:
结果分析:当进程bb的CPU占用时间等于它需要的执行时间时,进程bb度完成。则这时进程调度中还有两个进程:进程aa进程cc
结果分析:当调度进程中只剩下进程aa程cc这时根据进程优先级的大小,进程aa入运行态。当进程aa调度时,进程调度程序中直剩下进程cc这时进程cc进入运行态,而当前就绪队列将为空。
直到:
结果分析:当进程i的CPU占用时间等于所需要的执行时间时,进程cc调度完成,则这时进程调度中已经没有需要调度的进程了,则整个进程调度完成。
2、编写并调试一个模拟的进程调度程序,采用“轮转法”调度算法对五个进程进行调度。
轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。
简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还为完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。
将老师给的源程序修改成简单的时间片轮转法 流程图如下:
开始 初始化PCB,输 各进程按FCFS原则 所有 就绪队列首进 时间片到, 运行进程已占用 插入把运行进程进程完
时间片轮转法 #include #define getpch(type) (type*)malloc(sizeof(type)) #define NULL 0 #define TIME 2//时间片长度 ///////////// typedef struct pcb{ //////进程管理块 char name[10];///////进程名字 char state; int queue; int ntime; int rtime; int etime; ///////进程状态 //////进程所在的队列 /////进程需要运行的时间 //////进程已经运行的时间 ////进程在本队列可运行的时间片 struct pcb *link; }PCB; PCB *ready = NULL, *pinsert = NULL, *pfend = NULL,*p =NULL; 列,进程插入位置的变量*/ int geti() //使用户仅能输入整数 { char ch; int i = 0; fflush(stdin); ch = getchar(); while(ch == '\\n'){ } while(ch != '\\n'){ if(ch > '9' || ch < '0'){ printf(\"\输入有误!!输入只能为正整数,请重新输入...\\n\"); fflush(stdin); i = 0; ch = getchar(); printf(\"\f输入不能为空..请重新输入\\n\"); fflush(stdin); ch = getchar(); /*就绪队 } }else{ } i = i*10 + (ch - '0'); ch = getchar(); return i; } void findpos()///////更新状态量 { PCB *ps = pfend; if(!ps || !ps -> link || (ps-> link->queue - ps->queue) > 1) pinsert = ps; else{ } } void insert()//////插入进程 { if(!ready ){ ready = p; pfend = p; pinsert = p; while (ps->link && ps ->link->queue != (pfend ->queue +2)) ps = ps->link; pinsert = ps; }else if(ready ->queue == 1) //////第一队列存在 { p->link = pfend->link; pfend->link = p; pfend = p; findpos(); } Else { p->link = ready; ready = p; findpos(); } } void input()/*建立进程控制块函数*/ { int i,num; printf(\"\\n请输入进程的个数:\"); num = geti(); for(i=0; i < num; i++) { printf(\"\\n进程号No.%d:\\n\ p=getpch(PCB); printf(\"\\n输入进程名:\"); scanf(\"%s\ printf(\"\\n输入进程运行时间:\"); p ->ntime = geti(); } } printf(\"\\n\"); p->rtime=0; p->state='w'; p->queue =1; p->etime = TIME; p->link=NULL; insert();/*调用insert函数*/ void disp(PCB *pr)/*建立进程现实函数,用于显示当前进程*/ { printf(\"\\nname\ state\ queue\ ntime\ rtime\在队列可停留时间\ \\n\"); printf(\"|%s\\ printf(\" |%c\\ printf(\" |%d\\ printf(\" |%d\\ printf(\" |%d\\ printf(\" |%d\\ printf(\"\\n\"); } void check()/*建立进程查看函数*/ { PCB *pr; printf(\"\\n ****当前正在运行的进程是:%s\显示当前运行的进程*/ disp(ready); pr= ready ->link; printf(\"\\n****当前就绪队列状态为:\\n\");/*显示就绪队列状态*/ while(pr!=NULL) { } } void sort()//调整进程队列 { if(!ready->link ||ready->queue < ready->link->queue) return; p = ready ->link; ready ->link = pinsert ->link; pinsert ->link = ready; pinsert = ready; ready = p; if (ready && ready -> queue == pinsert ->queue){ } } void addnew()//添加新的进程 { if(ready ->queue != 1){ (ready -> queue)++; ready->etime *= 2; ready -> state='w'; findpos(); disp(pr); pr=pr->link; sort();/*调用sort函数*/ input(); } else{ } } void destroy()/*建立进程撤销函数(进程运行结束,撤销进程)*/ { printf(\"\\n进程[%s]已完成.\\n\ p = ready; ready = ready->link; free(p); if (ready && ready -> queue == pinsert ->queue) } void running()/*建立进程就绪函数(进程运行时间到,置就绪状态)*/ { (ready -> rtime)++; ready ->etime --; if(ready->rtime == ready->ntime){ destroy(); return; findpos(); input(); }else if(ready ->etime == 0){ int time = 2; (ready -> queue)++; } } for(int i = 2; i != ready->queue; ++i) time *= 2; ready->etime = time; ready -> state='w'; sort();/*调用sort函数*/ void main() { char ch; input(); while(ready != NULL) { } printf(\"\\n\\n 进程已经完成\\n\"); getchar(); } printf(\"\\nThe execute name:%s\\n\ready ->state = 'R'; check(); running(); printf(\"\\n按i键添加新进程....按其他任意键继续运行...\"); fflush(stdin); ch = getchar(); if (ch == 'i'|| ch=='I') addnew(); 运行结果如下: 根据题意输入五个进程 按任意键继续 四、实验问题及原因 (1)本次试验,思路设计不难 在这个多级反馈的实验中,我采取 了用一条实际上的链表队列来模拟多个逻辑上的队列,通过维护几个链表的状态信息来找到每个进程运行完后应该插入的地方,还有一个标志位Fend用来表明新插入的队列的位置。 (2)在建立优先数就绪队列时主要运用,链表插入模型。但是由于本题是从建立、到完成一个就绪对列,所以必须分多种情况讨论。 五、实验体会和收获 (1)本次试验后对优先数调度算法和时间片轮转调度算法实现的过程,有了很清楚的认识、理解。设计计数器来对进程执行状态的时间分析,使得进程调度这一抽象模型得到具体化。之后,便是对进程的插入(执行完,插入到完成队列,否则插入到就绪)和再次调度(当改进程再次满足条件时,从就绪队列调度到执行队列)重复过程。 (2)通过设计PCB结构,模拟进程调度,加深了对进程的理解。 (3)提高了C语言编程动手能力 因篇幅问题不能全部显示,请点此查看更多更全内容