模拟进程调度功能(操作系统原理实验)
设计进程调度功能,至少模拟两种以上调度算法。如:优先级调度算法、时间片调度算法等。进程调度功能作为一个函数 scheduler,加入到实验题目一中。 进程调度程序从就绪队列中挑选进程,若队列为空,应显示“无就绪进程无法调度”的提示信息。若选上一个进程,以显示:进程名、状态、时间片、优先级等信息表示一个进程被执行。若运行完,应删除相应 PCB。
0 💪实验目的
通过本实验,进一步掌握进程调度的功能和实现原理。
1 💪实验内容
设计进程调度功能,至少模拟两种以上调度算法。如:优先级调度算法、时间片调度算法等。
进程调度功能作为一个函数 scheduler,加入到实验题目一中。
进程调度程序从就绪队列中挑选进程,若队列为空,应显示“无就绪进程无法调度”的提示信息。
若选上一个进程,以显示:进程名、状态、时间片、优先级等信息表示一个进程被执行。若运行完,应删除相应 PCB。
2 💪实验要求
在实验题目一中的主菜单中加入一个菜单项:6 调度,选择该菜单项后,系统进入进程调度。
进程调度的结构:
3 💪各功能简要说明
返回主菜单:当用户选择该项功能时,系统退出进程调度功能,返回到实验题目一中的主菜单。
优先级调度:选择该功能选项时,系统将从就绪队列中选择优先级最高的进程,使该进程处于执行状态(将进程 PCB 的内容显示在屏幕上,显示完成后,该进程结束,即撤销该进程的 PCB)
时间片调度:每选择一次该功能,将就绪队列中所有进程的内容显示在屏幕上,并将每个执行进程的执行时间减去一个时间片,若某进程的剩余时间小于等于 0,则表明该进程运行结束,撤销该进程的 PCB。
4 💪实验代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN sizeof(pnode)
typedef struct pnode{
char name[10];
int time;
int level; //优先级
int status; //状态(0:就绪,1:执行,2:阻塞)
struct pnode *next;
}pnode,*PCB;
void push(PCB q,PCB p){ //放入
PCB n;
for(n=q;n->next;n=n->next);
p->next=NULL;
n->next=p;
}
void pop(PCB q,PCB p){ //取出
PCB n,m;
for(n=q;strcmp(n->next->name,p->name)!=0;n=n->next);
m=n->next->next;
n->next=m;
}
int nametest(PCB q,char name[]){ //进程名检测
PCB p;
for(p=q->next;p;p=p->next)if(strcmp(p->name,name)==0)return 0;
return 1;
}
void showlist(PCB q){ //显示一个队列里的所有进程
PCB p=q->next;
if(p)for(p=q->next;p;p=p->next){
printf("\n*****进程名:%s ", p->name);
printf ("进程时间:%d ",p->time);
printf("进程优先级:%d ",p->level);
printf("进程状态:%d\n",p->status);
}
else printf("此队列为空!\n");
printf("\n");
}
void create(PCB ready,PCB run,PCB block,int method){ //进程创建,进入就绪态
int flag = 1;
PCB p;
char name[10];
while(flag==1){
printf("请输入进程名:");
scanf("%s",name);
if(nametest(ready,name)!=0&&nametest(run,name)!=0&&nametest(block,name)!=0){
printf("命名有效,新进程已创建\n");
p=(PCB)malloc(LEN);
strcpy(p->name,name);
printf("请输入该进程的运行时间:");
scanf("%d",&p->time);
printf("请输入该进程的优先级:");
scanf("%d",&p->level);
p->status=0;
p->next=NULL;
push(ready,p);
printf("进程%s已成功创建,",name);
}
else printf("该名称的进程已存在,\n");
if(!run->next&&method==1){
printf("执行队列为空,将调用新的进程进入执行态\n");
runs(ready,run,method);
}
printf("是否继续创建其他进程(1:是 0:否):");
scanf("%d",&flag);
}
}
void prior(PCB ready,PCB run){ //高优先权调度算法
PCB p,q;
int tem=0;
if(run->next){
p=run->next;
pop(run,p);
free(p);
}
p=ready->next;
while(p){
if(p->level>tem){
tem=p->level;
q=p;
}
p=p->next;
}
pop(ready,q);
push(run,q);
q->status=1;
printf("调度成功!调度进程信息:\n");
printf("进程名:%s 进程优先级%d\n",q->name,q->level);
}
void times(PCB ready,PCB run){ //时间片轮转算法
int t;
PCB p;
printf("请输入时间片的长度:");
scanf("%d",&t);
for(;;){
p=ready->next;
pop(ready,p);
p->status=1;
push(run,p);
p->time-=t;
pop(run,p);
if(p->time<=0)free(p);
else{
p->status=0;
push(ready,p);
}
if(!ready->next){
printf("所有进程执行完毕!\n");
return;
}
printf("时间片到,就绪队列的进程信息如下:\n");
showlist(ready);
printf("输入任意键来进行下一个时间片");
getch();
}
}
void runs(PCB ready,PCB run,int method){ //进程调度 就绪态->执行态
if(!ready->next){
printf("就绪队列为空,无法执行调度!\n");
return;
}
int flag=1;
while(flag==1){
switch(method){
case 1:prior(ready,run);break;
case 2:times(ready,run);break;
}
if(ready->next){
printf("是否继续调度其他进程(1:是 0:否):");
scanf("%d",&flag);
}
else
flag=0;
}
}
void blocks(PCB ready,PCB run,PCB block,int method){ //进程阻塞 执行态->阻塞态
PCB p=run->next;
if(!p){
printf("执行队列为空,无法执行阻塞!\n");
return;
}
pop(run,p);
push(block,p);
p->status=2;
printf("进程%s已阻塞,",p->name);
printf("执行队列为空,将调用新的进程进入执行态\n");
runs(ready,run,method);
}
void wakeup(PCB ready,PCB run,PCB block,int method){ //进程唤醒 阻塞态->就绪态
int flag=1;
PCB p=block->next;
if(!p){
printf("阻塞队列为空,无法进行唤醒!\n");
return;
}
char name[10];
while(flag==1){
printf("请输入要唤醒的进程名:");
scanf("%s",name);
for(;;p=p->next){
if(!p){
printf("阻塞队列没有名称为%s的进程,",name);
break;
}
else if(strcmp(p->name,name)==0){
pop(block,p);
push(ready,p);
p->status=0;
p->next=NULL;
printf("进程%s已成功唤醒,",p->name);
if(!run->next){
printf("执行队列为空,将调用新的进程进入执行态\n");
runs(ready,run,method);
}
break;
}
}
printf("是否继续唤醒其他进程(1:是 0:否):");
scanf("%d",&flag);
}
}
void del(PCB ready,PCB run,PCB block,int method){ //撤销进程
PCB p;
char name[10];
int flag=1;
int finish;
while(flag==1){
finish=0;
printf("请输入要撤销的进程名:");
scanf("%s",name);
for(p=ready->next;;p=p->next){
if(!p)break;
else if(strcmp(p->name,name)==0){
finish=1;
break;
}
}
if(finish==0)for(p=run->next;;p=p->next){
if(!p)break;
else if(strcmp(p->name,name)==0){
finish=2;
break;
}
}
if(finish==0)for(p=block->next;;p=p->next){
if(!p)break;
else if(strcmp(p->name,name)==0){
finish=3;
break;
}
}
if(finish==1)pop(ready,p);
else if(finish==2)pop(run,p);
else if(finish==3)pop(block,p);
if(finish!=0){
printf("进程%s已成功撤销,",p->name);
free(p);
if(!run->next){
printf("执行队列为空,将调用新的进程进入执行态\n");
runs(ready,run,method);
}
}
if(finish==0)printf("内存中没有名称为%s的进程,",name);
printf("是否继续撤销其他进程(1:是 0:否):");
scanf("%d",&flag);
}
}
void show(PCB ready,PCB run,PCB block){ //显示所有进程
printf("进程信息如下:\n\n");
printf("就绪队列:");
showlist(ready);
printf("执行队列:");
showlist(run);
printf("阻塞队列:");
showlist(block);
}
void menu(int method){ //菜单
PCB ready,run,block;
int select,flag=1;
ready=(PCB)malloc(LEN);
run=(PCB)malloc(LEN);
block=(PCB)malloc(LEN);
ready->next=NULL;
run->next=NULL;
block->next=NULL;
while(flag==1){
printf("*****主菜单\n");
printf("*****请输入0~6来选择相应操作:\n");
printf("*****1------创建进程\n");
printf("*****2------调度进程\n");
printf("*****3------阻塞进程\n");
printf("*****4------唤醒进程\n");
printf("*****5------撤销进程\n");
printf("*****6------显示进程\n");
printf("*****0------返回上一层\n");
printf("请选择操作:");
scanf("%d",&select);
printf("\n");
switch(select){
case 1: create(ready,run,block,method);break;
case 2: runs(ready,run,method);break;
case 3: blocks(ready,run,block,method);break;
case 4: wakeup(ready,run,block,method);break;
case 5: del(ready,run,block,method);break;
case 6: show(ready,run,block);break;
case 0: flag=0;break;
default: printf("输入有误!");break;
}
printf("\n");
}
}
void main(){
int flag=1;
int select;
while(flag==1){
printf("系统调度算法\n");
printf("*****1------高优先权优先调度\n");
printf("*****2------时间片轮转调度\n");
printf("*****0------退出\n");
printf("请输入选择:");
scanf("%d",&select);
switch(select){
case 1:
case 2:menu(select);break;
case 0:flag=1;break;
default:printf("输入错误!\n");break;
}
}
}
5 💪实验结果
6 💪实验总结
调试程序出现了下面的等诸多问题:
在写getch()函数时,系统报错
解决办法:缺少了#include<conio.h>头文件。
为了解决控制台杂乱的问题,我写了清屏函数,但是清屏函数的位置放错了。
解决办法:经过重新检查,放在了合适的位置,达到了预期的要求
在实现高优先权和时间片轮算法的过程中,代码运行出现了错误。
解决办法:通过翻书重新梳理两种算法的实现过程,然后,通过简要的梳理,重新分析了程序。
在写链表传递过程中,出现了错误。
解决办法:经过认真的分析,重新写代码,解决了这个问题。
在写创建进程函数时,未能按照要求实现
解决办法:根据老师所给的PPT,重新思考,重新写了代码,运行正确。
7 💪实验程序以及实验报告下载链接
操作系统原理实验:内含实验报告和实验视频希望能够给正在写实验报告的同学提供一定程度上的帮助如果需要讨论可以与我私信,相帮助-OS文档类资源-CSDN文库
更多推荐
所有评论(0)