1、操作系统进程调度实验报告操作系统进程调度实验报告一.实验目的 用高级语言编写和调试一个进程调度程序以加深对进程的概念及进程调度算法的解( 进程调度时进程管理的主要内容之一通过设计编制调试一个简单的进程调度模拟系统对进程调度进程运行状态变换加深理解和掌握。模拟计算机操作系统的进程调度,建立进程控制块PCB,要包含有关进程的描述信息,控制信息以及资源信息.模拟系统根据PCB感知进程的存在和通过PCB中所包含的各项变量的变化,掌握进程所处的状态以达到控制进程活动的目的.要实现进程的状态及其转换,进程的创建与撤消,进程的阻塞与唤醒.用P,V原语操作实现进程互斥. 二.实验要求 建立进程控制块PCB,用
2、PCB实现进程在运行过程中的一切状态,未创建、就绪、运行、等待、退出.以完成资源的共享,实现进程的同步与互斥.程序要求用p,v操作实现进程互斥. 三.实验平台 Windows XP 下的Microsoft vitual c+平台 四.所用语言 Microsoft Visual C+语言 五.机器要求 Microsoft Windows XP Professional 版本 2002 Service Pack 256MB内存 SVGA(800600分辨率256色或更高级的显示卡 鼠标或其他相容设备 六.系统分析 设计建立四个进程,模拟模拟批处理多道操作系统的进程调度, 进程调度算法,采用最高优先
3、数优先的调度算法.每个进程有一个进程控制块, PCB,表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为地指定,也可以由随机数产生,。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪 W,Wait,、运行R,Run,、或完成F,Finish,三种状态之一。就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。 如果运行一个时间片后进程的已占用 CPU时间已达到所需要的运行时间则撤消该进程如果运行一个时间片后进程的已占用CPU时间还未达所
4、需要的运行时间也就是进程还需要继续运行此时应将进程的优先数减1,即降低一级,然后把它插入就绪队列等待CPU。每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB以便进行检查。重复以上过程直到所要进程都完成为止。 同时,以上操作执行完了以后,要反映出在这个操作过程中p原语和v原语操作的执行情况,于是调用预先创建的函数.并输出p,v操作在整个程序过程中的执行情况和状态.于是我们创建四个进程process1,process2,process3,process4具体反应p,v原语对四个进程的操作.要预先说明的是,在四个进程并不是与输入的四个进程一一对应.输入的四个进程要按照优先级的高
5、低来确定它们执行的顺序,优先级从高到低顺序执行,所以创建的process1到process4四个进程函数与输入的四个进程的执行顺序是一一对应的,也就是说,优先级最高的与process1对应,依次下来.这样我们创建的四个进程函数才能正确反映p,v原语对四个具体进程的操作过程. 过程运行中除了调用P操作申请信号量外还要调用V操作释放信号量V操作在释放信号量之后还将唤醒因申请此信号量而被阻塞的过程。 在程序运行的四个过程,PROCESS1,PROCESS2,PROCESS3,PROCESS4,其中过程运行中通过P操作申请信号量1过程2通过V操作释放信号量2然后做一次操作申请信号量2。四个过程的运行通
6、过进程调度模块同意安排调度模块通过FIND()函数找到第一个就绪过程如果当前没有过程已在运行就直接运行此过程如果有则比较两者的优先数然后运行优先权高者。 七.系统功能 因为没有设计动化效果,所以没有对系统功能详细说明.只是输出/输入语句. 八.数据结构 进程控制块1PCB struct int id; char status; int priority; int waiter1; pcb5; 信号量 struct int value; int waiter2; sem4; 现场保护栈stack char stack114 每个进程都有一个大小为10个字的现场保护栈用来保护被中断时的断点地址等信
7、息。 全局变量 int i; 用以模拟一个通用寄存器 char addr; 用以模拟程序计数器 int m1,m2;为系统设置的公用数据被三个进程共享使用 定义进程控制块2PCB struct pcb char name10; char state; int super; int ntime; int rtime; struct pcb* link; *ready=NULL,*p; 现场保护栈: char stack115 每个进程都有一个大小为11个字的现场保护栈,用来保护被中断时的断点地址等信息. 全局变量 int i; 用以模拟一个通用寄存器 char addr; 用以模拟程序计数器 i
8、nt m1,m2;为系统设置的公用数据被四个进程共享使用. int num;确定进程数量 struct int id; /进程标号 int waiter1; /指针用于标识等待队列的下一个进程 int priority; /进程优先级 char status; /进程状态 Pcb5;进程控制快Pcb 九.分工情况 在我们小组合作的过程中,由我们三个人共同完成,具体的分工是这样的: 框图设计和编写程序代码由许向前和申友明共同完成,因为框图和程序紧密相连. 整个幻灯片设计是由杨毅完成 十.讨论情况 第一次讨论 时间:2005 11 1 地点:12栋116寝室 主持:申友明 内容:讨论这次作业的合作
9、和分工情况,并认真阅读老师给的辅助资料. 第二次讨论 时间:2005 11 10 地点:12栋116寝室 主持:杨毅 内容:一起参阅了一些相关的资料和源代码,并构建整个作业的大约流程图. 第三次讨论 时间:2005 11 17 地点:12栋116寝室 主持:许向前 内容:具体完成了分工操作,并将我们完成的部分集中在一起,反复修改,由杨毅负责的整个课件基本形成.最后一次讨论是在 对我们所努力产生的成果从总体上进行包装.作业完成. 十一.流程图 流程图一. 流程图二. 流程图三 流程图四 流程图五 流程图六 流程图七 流程图八 流程图九 流程图十 流程图十一. process4() add=m?
10、add=n i=1 返回0 调用P操作并判断带回值=0? m1=i Printf(“proce3 call V on sem1 m1=%dn”,m1) 调V操作并判断返回值=0? Printf(“proce3 i=%dn”,i) 返回0 i=i+10 十二.程序代码 #include #include iostream.h #include #define num 4 #include #define getpch(type) (type*)malloc(sizeof(type) #define NULL 0 int m1; /共享变量 int m2; /共享变量 struct int id;
11、 /进程标号 int waiter1; /指针用于标识等待队列的下一个进程 int priority; /进程优先级 char status; /进程状态 Pcb5; struct int value; /信号量的值 int waiter2; /指针用于标识等待此信号量队列的第一个进程 sem4; char stack115; /现场保护堆栈 int i; /cpu中的通用寄存器 int ep; /当前运行进程指针 char addr; /程序运行时的地址 void init(); /初始化 int find(); /找出就绪进程 int w2(); / int process1(); /进程
12、1 int process2(); /进程2 int process3(); /进程3 int process4(); /进程4 int P(int,int ,char); /P原语 int V(int,int ,char); /V原语 /* struct pcb /* 定义进程控制块PCB */ char name10; char state;/状态 int super;/最先判别优先级 int waittime;/等待时间 int xtime; int ntime; int rtime; struct pcb* link; *ready=NULL,*p,*t=NULL; typedef s
13、truct pcb PCB; /* void init() /初始化进程 int j,k; Pcb0.status=w; /进程状态设置为等待 Pcb0.priority=5; /进程的优先级别 for(j=1;j=4;j+) Pcbj.id=j; /进程编号 Pcbj.status=r; /进程状态设置为就绪 Pcbj.waiter1=0; /进程指针初始化为0 Pcbj.priority=j; /设置进程优先级 for(j=1;j=3;j+) semj.value=1; /信号量赋值为1 semj.waiter2=0; /等待信号量队列的初始化 i=0; /CPU通用寄存器初始化 ep=0
14、; / addr=0; /程序运行地址 m1=0; /共享变量初始化 m2=0; /共享变量初始化 for(j=1;j=10;j+) for(k=1;k=4;k+) stackjk=0; /现场保护堆栈初始化 int find() /查找初始化变量 int j; for(j=1;j=4;j+) if(Pcbj.status=r) return(j); /如果pcb队列中有就绪进程返回进程编号 return(0); int w2() /进程调度程序 int pd; pd=find(); /找出就绪进程编号 if(pd=0) return(0); /如果没有找到就绪进程退出程序 else if(e
15、p=0) /如果当前运行进程是否为0 Pcbpd.status=e; /直接将当前进程设置为运行状态 ep=pd; /当前运行进程设置为pd printf(进程%d正在执行n,ep); else if(Pcbpd.priority4) printf(进程3在信号量sem3上调用P操作n); if(P(3,3,m)=0) return(0); / m: m1=3*m2; printf(进程3在sem2信号量上调用V操作m=%dn,m2); if(V(2,3,n)=0) return(0); else n: printf(打印进程3.i=%dn,i); i+=15; goto a; int pro
16、cess4() if(addr=m) goto m; if(addr=n) goto n; i=1; a: if(i4) printf(进程4在信号量sem3上调用P操作n); if(P(3,4,n)=0) return(0); n: m2=i; printf(进程4在sem3信号量上调用V操作m=%dn,m2); if(V(3,4,m)=0) return(0); else m: printf(打印进程4.i=%dn,i); i+=1; goto a; int P(int se,int P,char ad)/p操作 int w; semse.value-; /信号量减1 if(semse.v
17、alue=0) return(1); /如果信号量,0返回1说明阻塞 printf(阻塞当前进程%dn,P); PcbP.status=w; /改变进程状态 ep=0; /运行进程为空 PcbP.waiter1=0; /设为尾末 w=semse.waiter2; /找出等待队列的队尾 if(w=0) semse.waiter2=P; /插入等待队列 else while(Pcbw.waiter1!=0) w=Pcbw.waiter1; Pcbw.waiter1=P; stack1P=i; /保存现场 stack2P=ad; return(0); int V(int se,int P,char
18、ad)/v操作 int w; semse.value+; /信号量加1 if(semse.value0) return(1); /信号量0无等待进程 w=semse.waiter2; /返回第一个等待进程 semse.waiter2=Pcbw.waiter1; /调整位置 Pcbw.status=r; /进程改变状态 printf(唤醒进程%dn,w); stack1P=i; /进程状态进栈 stack2P=ad; return(0); sort() /* 建立对进程进行优先级排列函数*/ PCB *first, *second; int insert=0; if(ready=NULL)|(p
19、-super)(ready-super) /*优先级最大者,插入队首*/ p-link=ready; ready=p; else /* 进程比较优先级,插入适当的位置中*/ first=ready; second=first-link; while(second!=NULL) if(p-super)(second-super) /*若插入进程比当前进程优先数大,*/ /*插入到当前进程前面*/ p-link=second; first-link=p; second=NULL; insert=1; else /* 插入进程优先数最低,则插入到队尾*/ first=first-link; seco
20、nd=second-link; if(insert=0) first-link=p; sort1() p-link=t; ready=p; input() /* 建立进程控制块函数*/ int i; /clrscr(); /*清屏*/ /printf(n 请输入进程号:); /scanf(%d,&num); for(i=0;iname); printf(n 输入进程优先数:); scanf(%d,&p-super); printf(n阻塞进程的时间片 :); scanf(%d,&p-waittime); printf(n 进程要运行的时间:); scanf(%d,&p-ntime); prin
21、tf(n阻塞时间:); scanf(%d,&p-xtime); printf(n); p-rtime=0; p-state=w; p-link=NULL; sort(); /* 调用sort函数*/ int space() int l=0; PCB* pr=ready; while(pr!=NULL) l+; pr=pr-link; return(l); disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/ printf(n qname t state t waittime t ndtime t runtime t xtimen); printf(%st,pr-name);
22、 printf( ); printf(%ct,pr-state); printf( ); printf(%dt,pr-waittime);printf( ); printf(%dt,pr-xtime); printf( ); printf(%dt,pr-ntime); printf( ); printf(%dt,pr-rtime);printf( ); printf(n); check() /* 建立进程查看函数 */ PCB* pr; PCB* pp; printf(n*当前正在运行的进程是:%s,p-name); /*显示当前运行进程*/ disp(p); pr=ready; printf
23、(n*当前就绪队列状态为:n); /*显示就绪队列状态*/ while(pr!=NULL) disp(pr); pr=pr-link; pp=t; printf(n阻塞队列状态为:n); while(pp!=NULL) disp(pp); pp=pp-link; disp(pr); pr=pr-link; destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/ printf(n 进程 %s 已完成.n,p-name); free(p); running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ PCB *ptr; while(p-rtime!=p-ntime) p-rtime+; printf(n当前所运行的进程状态为:); disp(p); ptr=t; while(ptr!=NULL) ptr-xtime-; if(ptr-xtime=0) p=ptr; sort(); ptr-link=ptr; if(p-rtime=p-waittime) printf(n该进程被阻塞:); sort1(); break; if(p-rtime=p-ntime) destroy(); /
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1