进程调度.docx
- 文档编号:10528393
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:27
- 大小:1.05MB
进程调度.docx
《进程调度.docx》由会员分享,可在线阅读,更多相关《进程调度.docx(27页珍藏版)》请在冰豆网上搜索。
进程调度
课题一:
进程调度模拟
1、设计目的
通过对进程调度算法的设计,深入理解进程调度的原理,同时掌握进程调度算法的实现方法和技巧。
2、任务及要求
1.用语言来实现对n个进程采用不同调度算法的进程调度。
2.每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:
(1)进程优先数ID,其中0为闲逛进程,用户进程的标识数为1,2,3…。
(2)进程优先级Priority,闲逛进程(idle)的优先级为0,用户进程的优先级大于0,且随机产生,优先数越大,优先级越高。
(3)进程占用的CPU时间CPUtime,进程每运行一次,累计值等于4。
(4)进程总共需要运行时间Alltime,利用随机函数产生。
(5)进程状态,0:
就绪态;1:
运行态;2:
阻塞态。
(6)队列指针next,用来将多个进程控制块PCB链接为队列。
3.优先数改变的原则
(1)进程在就绪队列中每呆一个时间片,优先数增加1。
(2)进程每运行一个时间片,优先数减3。
4.在调度前,系统中拥有的进程数PCB_number由键盘输入,经初始化后,所有的进程控制块PCB链接成就绪队列。
3、算法及数据结构
3.1算法的总体思想
先到先服务算法,给每个进程定一个进程号,然后按照进程号顺序进行即可。
最短作业优先算法要判断作业的alltime时间,alltime最小的最先执行,依次按照时间从小到大执行进程。
优先度调度算法,要先判断优先度的大小,优先度最大的先执行,进程运行完毕以后,按照优先数的改变的原则进行改变,然后继续判断所有的优先数的大小,依旧是优先数最大的先执行,直到执行完毕。
RR时间片轮转调度算法,要依次执行时间片用完即阻塞,转交给下一个进程执行,直到所有进程运行完。
3.2数据结构模块
3.2.1功能
进程的结构体声明与函数的声明
3.2.2数据结构
structProcess
{
intPro_Id;//进程编号ID
intPriority;//进程优先级,随机产生
intCPUtime;//进程占用的CPU时间CPUtime
intAlltime;//进程共需运行时间,随机产生
intState;//进程状态
structProcess*Next;
};
/****************函数声明*******************/
intrandom_num();//随机数字产生
structProcess*INITIAL(int*n);//进程的初始化
intprintall(structProcess*P1);//打印所有进程的具体信息
intget_maxpri(structProcess*P1);//获取优先度最高的进程号
intget_mintime(structProcess*P1);//获作业时间最短的进程号
voidalert_status(structProcess*P1,intm);//修改进程的状态
voidalert_pri(structProcess*P1,intm);//修改进程的优先度
voidFCFS(structProcess*Head);//先来先服务算法
voidPriority(structProcess*Head,intn);//优先级调度算法
structProcess*alert_sjf(structProcess*P2,intm);//修改sjf算法状态
voidSJF(structProcess*Head,intn);//SJF调度算法
voidRR(structProcess*Head,intn);//RR时间片调度算法
3.3随机数字产生方法模块
3.3.1功能
随机产生数字,用于进程初始化时的优先度与alltime赋值
3.3.2数据结构
intrandom_num()
3.3.3算法
intrandom_num()
{
intm;
m=rand()%100;
if(m==0)
m=1;
returnm;
}//随机数函数结束
3.4先到先服务(FCFS)模块
3.4.1功能
模拟进程的先到先服务调度算法,按照进程编号依次运行。
3.4.2数据结构
voidFCFS(structProcess*Head);//先来先服务算法
printall(structProcess*Head);//打印所有进程信息
3.4.3算法
voidFCFS(structProcess*Head)
{
structProcess*P1,*P2;
P1=Head;
while(P1!
=NULL)
{
P1->State=1;
//printf("%3d\n",P1->State);
P2=Head;
printall(P2);
printf("按任意键,继续演示.......\n");
getchar();
P1->CPUtime=P1->Alltime;
P1->State=3;
//printf("%3d号进程运行完毕\n",P1->Pro_Id);
//Sleep(1000+P1->Alltime*10);
P1=P1->Next;
}//while
P2=Head;
printall(P2);
printf("演示结束,谢谢。
\n");
}//FCFS结束
3.5SJF(最短作业优先)调度算法模块
3.5.1功能
将每个进程与其下一个CPU区间段相关联。
当CPU为可用时,它会赋给具有最短后续CPU区间的进程。
如果两个进程具有同样长度的CPU区间,那么可以使用FCFS调度来处理。
3.5.2数据结构
voidSJF(structProcess*Head,intn)
intget_mintime(structProcess*P1)
structProcess*alert_sjf(structProcess*P2,intm)
3.5.3算法
/**SJF调度算法**/
voidSJF(structProcess*Head,intn)
{
intm;
inti;
structProcess*P2,*P;
P=NULL;
for(i=0;i { P2=Head; m=get_mintime(P2); printf("\n在未完成的进程中%d号进程需要运行时间最短\n\n",m); P2=Head; P=alert_sjf(P2,m); P2=Head; printall(P2); P2=Head; P->State=3; P->CPUtime=P->Alltime; P=NULL; printf("按任意键,继续演示.......\n"); getchar(); } P2=Head; printf("\n所有进程运行结束。 \n\n"); printall(P2); printf("SJF算法演示完毕,谢谢使用\n"); } /**获取进程最短时间**/ intget_mintime(structProcess*P1) { intk,m; k=1001; m=0; while(P1! =NULL) { if(k>P1->Alltime&&P1->State! =3) { k=P1->Alltime; m=P1->Pro_Id; }//if P1=P1->Next; }//while returnm; } /**修改sjf算法状态**/ structProcess*alert_sjf(structProcess*P2,intm) { structProcess*P1,*P; intk=0; P1=P2; P=NULL; while (1) { if(P1->Pro_Id==m) { P1->State=1; P=P1; k=1; }//if else { P1=P1->Next; } if(k==1) break; }//while returnP; } 3.6优先级调度算法模块 3.6.1功能 1.每个进程被赋予一个优先级数字(优先权) 2.CPU分配给优先权高的进程(优先级数字越小,则优先权越大) 3.6.2数据结构 voidPriority(structProcess*Head,intn) intget_maxpri(structProcess*P1) voidalert_pri(structProcess*P1,intm) voidalert_status(structProcess*P1,intm) 3.6.3算法 /**优先级调度算法**/ voidPriority(structProcess*Head,intn) { structProcess*P1,*P2; intkey=0; intm; P1=Head; P2=Head; //printf("%d\n",n); //printf("%d\n",key); while(key { m=get_maxpri(P2);//获取优先级最高的进程ID //printf("%d\n",m); alert_status(P1,m);//修改进程的运行状态等信息 P2=Head; if(printall(P2)) key++; P1=Head; alert_pri(P1,m);//修改进程的优先级 printf("按任意键,继续演示.......\n"); getchar(); //printf("%d\n",key); } printf("所有进程已经全部结束! ! ! "); key=0; } /**获取优先度最高的进程号**/ intget_maxpri(structProcess*P1) { intk,m; k=P1->Priority; m=P1->Pro_Id; while(P1->Next! =NULL) { if(k { k=P1->Next->Priority; m=P1->Next->Pro_Id; }//if P1=P1->Next; }//while returnm; } /**修改进程的优先度**/ voidalert_pri(structProcess*P1,intm) { structProcess*P2; intk; k=0; P2=P1; while(P2! =NULL) { if(P2->Priority>0) { if(P2->Pro_Id! =m) { P2->Priority=P2->Priority+1; }//if else { P2->Priority=P2->Priority-3; }//else if(P2->Priority<=0) { P2->Priority=0; P2->State=3; }//if }//if P2=P2->Next; }//while }//修改进程优先度函数结束 /**修改进程的状态**/ voidalert_status(structProcess*P1,intm) { structProcess*P2; //intstatus; P2=P1; while(P2! =NULL) { if(P2->Pro_Id==m) { P2->State=1; }//if else { if(P2->State==1) P2->State=2; }//else P2=P2->Next; }//while }//修改进程状态结束 3.7时间片轮转调度算法模块 3.7.1功能 如果就绪队列中有n个进程,且时间片为q,则每个进程会得到1/n的CPU时间,每个长度不超过q时间单元。 每个进程必须等待CPU的时间不会超过(n-1)q个时间单元,直到它的下一个时间片为止 3.7.2数据结构 voidRR(structProcess*Head,intn) 3.7.3算法 /*****RR时间片调度算法****/ voidRR(structProcess*Head,intn) { structProcess*P2,*P1; intm=n; P2=Head; printall(P2); printf("按任意键,继续演示......."); getchar(); P2=Head; P1=Head; while (1) { while(P1! =NULL) { if(P1->State! =3) { P1->State=1; printall(P2); printf("按任意键,继续演示.......\n"); getchar(); P2=Head; if(P1->CPUtime+4 { P1->State=2; P1->CPUtime=P1->CPUtime+4; } else { P1->CPUtime=P1->Alltime; P1->State=3; printf("%d号进程已经运行完毕! ! ! ! \n\n",P1->Pro_Id); m--; }//else }//if P1=P1->Next; }//while if(m==0) break; else P1=Head; } P2=Head; printall(P2); printf("时间片轮转算法演示结束,谢谢使用。 \n"); } 3.8主函数模块 3.8.1功能 用于程序与用户的交互操作,由用户选择模拟实验的算法,并执行相应的算法。 3.8.2数据结构 intmain() 3.8.3算法 /***********主函数**************/ intmain() { structProcess*Head,*P1; inta; intk=1; //intm; intn; n=0; while(k==1) { system("cls"); P1=NULL; Head=NULL; srand((int)time(NULL));//该语句只需要一次递交种子就可以 printf("**********************实验模拟开始**************************\n"); printf("\n"); printf("\n"); printf("\n"); printf("1.先到先服务调度算法;\n"); printf("2.SJF(最短作业优先)调度算法;\n"); printf("3.优先度调度算法;\n"); printf("4.RR(轮转法)调度算法;\n"); printf("5.退出;\n"); printf("\n"); printf("\n"); printf("\n"); printf("*************************************************************\n"); printf("请输入您的选择: "); scanf("%d",&a); while(a! =1&&a! =2&&a! =3&&a! =4&&a! =5) { printf("对不起,您的选择有误,请重新选择"); scanf("%d",a); }//while if(a==1||a==2||a==3||a==4) { P1=INITIAL(&n); Head=P1; printall(P1); printf("初始化进程已完成.\n"); printf("\n按任意键实验开始演示: "); getchar(); getchar(); } switch(a) { case1: FCFS(Head); break; case2: SJF(Head,n); break; case3: Priority(Head,n); break; case4: RR(Head,n); break; case5: printf("感谢您使用该系统.再见~~\n"); k=0; break; }//switch printf("\n"); printf("\n"); printf("\n"); if(a==1||a==2||a==3||a==4) { printf("按任意键回到主菜单...."); getchar(); } }//while }//main 3.9进程的初始化模块 3.9.1功能 用于由用户输入进程数以后,对进程的初始化,并利用随机函数,随机生成进程的优先度与alltime,并赋值。 3.9.2数据结构 structProcess*INITIAL(int*n) 3.9.3算法 /**进程的初始化**/ structProcess*INITIAL(int*n) { structProcess*P1,*Head,*P2; inta=0; inti=0; P1=P2=Head=NULL; /**进程的输入**/ do{ printf("pleaseinputPCB_number(请输入进程数): \n"); scanf("%d",&a); }while(a==0);//do..while /**/ P1=(structProcess*)malloc(sizeof(structProcess)); Head=P1; for(i=1;i<=a;i++) { P1->Pro_Id=i; P1->Priority=random_num(); P1->CPUtime=0; P1->Alltime=random_num(); P1->State=0; if(i==a) { break; } P2=(structProcess*)malloc(sizeof(structProcess)); P1->Next=P2; P1=P2; }//for P1->Next=NULL; *n=a; returnHead; }//初始化函数结束 4、实验结果及分析 4.1实验结果 先到先服务算法演示: SJF(最短作业优先)调度算法演示: 优先度调度算法演示: RR(轮转法)调度算法演示: 4.2结果分析 1.intrandom_num()这个函数导致随机数产生以后,所有的随机数都是一个数。 问题原因是: 随机种子是传递给操作系统的,不是传递给函数的,所以,不必多次调用。 在一个程序中,种子只产生一次即可。 也就是说: srand((int)time(NULL));这句只出现在main函数里一次就可以 修改后运行结果: 2.进程开始执行以后当所有进程都结束后。 程序一直在运行,结束不了。 加入变量key表示已经完成的进程作为解决办法,但是当用指针处理的时候,发现打印出的是key的地址,但是用的是*key,最后只能用printall返回一个值表示有进程完成。 解决了问题,不明白为什么用*key不能打印出 数字而是地址 修改加入变量后结果是: 3.再次选择优先度算法时,运行输入一个进程的时候发现直接没有运行提示程序运行完毕 原因是第一次运行完成后,没有把key置0导致第二次运行的时候出现key==n,不执行while循环。 修改后执行:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 调度