优先级调度算法
1. 设计一个按优先数调度算法实现处理器调度的程序。 高手帮忙!!
#include <stdio.h>
#include <stdlib.h> //提供atoi()函数
#include <conio.c> //提供clrscr()函数
#define M 10 //字符串大小常量
#define N 3 //进程数常量
#define SLOT 2
typedef struct node{
char name[M];
int prio; //优先级
int round; //时间片长度
int cputime; //已经使用的cpu时间
int needtime;//需要多少cpu时间
int count; //计数器
char state; //进程的当前状态
struct node *next; //指向下一个进程
}PCB;
PCB *finish,*ready,*tail,*run;
void ShowHead(char *s1,char *s2);
int Menu_Select();
void Creat(int select);
void InsertPriority(PCB *q);
void InsertSlot(PCB *q);
void PrintOneProcess(int select,PCB *q);
void PrintAllProcess(int select);
void FirstIn();
void FIFODo(int select);
void PriorityDo(int select);
void SlotDo(int select);
void Quit();
main()
{
while(1)
{
clrscr();
switch(Menu_Select())
{
case 1:
Creat(1);
FIFODo(1);
printf("\n\n\t\t按回车键返回菜单...");
getchar();
getchar();
break;
case 2:
Creat(2);
PriorityDo(2);
printf("\n\n\t\t按回车键返回菜单...");
getchar();
getchar();
break;
case 3:
Creat(3);
SlotDo(3);
printf("\n\n\t\t按回车键返回菜单...");
getchar();
getchar();
break;
case 0:
Quit();
break;
}
}
}
/*打印每个界面的开头显示*/
void ShowHead(char *s1,char *s2)
{
printf("\t ==================%s========================\n\n",s1);
printf("\t\t\t\t%s\n\n",s2);
printf("\t ========================================================\n\n");
}
/*主菜单*/
int Menu_Select()
{
int choose;
char s[2];
clrscr();
printf("====================进程调度算法模拟程序=====================\n\n");
printf("\t\t 1.先进先出调度策略\n");
printf("\t\t 2.优先数调度策略\n");
printf("\t\t 3.时间片轮转调度策略\n");
printf("\t\t 0.退出系统\n\n");
printf("=============================================================\n\n");
do
{
printf("\n请输入你的选择(0-3):");
scanf("%s",s);
choose=atoi(s);
}while(choose<0 || choose>3);
return choose;
}
/*创建调度算法的链表*/
void Creat(int select)
{
PCB *p,*q; //q为就绪队列的最后一个结点
int i,time,rounds;
char na[M];
ready=NULL;
finish=NULL;
run=NULL;
if(select==1) //先进先出调度创建
{
printf("\nEnter name and time of process:\n");
for(i=1;i<=N;i++)
{
p=(PCB *)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='W';
p->next=NULL;
if(ready!=NULL) //就绪队列不为空
{
q->next=p;
q=p;
}
else //就绪队列为空
{
p->next=ready;
ready=p;
q=ready;
}
}
clrscr();
ShowHead("先进先出调度策略","FIFO dispatching algorithm ");
printf("\t\t name cputime needtime state\n");
PrintAllProcess(select); //打印出初始状态的信息
}
else if(select==2) //优先数调度创建
{
printf("\nEnter name and time of process:\n");
for(i=1;i<=N;i++)
{
p=(PCB *)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='W';
p->prio=50-time;
if(ready!=NULL) //就绪队列不为空的时候
InsertPriority(p);
else //就绪队列为空
{
p->next=ready;
ready=p;
}
}//end of for()
clrscr();
ShowHead("优先级调度策略","Priority dispatching algorithm ");
printf("\t\t name cputime needtime prio state\n");
PrintAllProcess(select); //打印出初始状态的信息
}//end of else if()
else if(select==3) //时间片轮转调度创建
{
printf("\nEnter name and the time of process:\n");
for(i=1;i<=N;i++)
{
p=(PCB *)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->count=0; //计数器
p->round=SLOT;
p->state='W';
if(ready!=NULL)
InsertSlot(p);
else
{
p->next=ready;
ready=p;
}
}
clrscr();
ShowHead("时间片轮转调度策略","Time slot dispatching algorithm ");
printf("\n\t\t name cputime needtime count slot state\n");
PrintAllProcess(select); //打印出初始状态的信息
}
run=ready; //从就绪队列取一个进程,使其运行,同时就绪队列的头指针后移
run->state='R';
ready=ready->next;
}
/*优先调度:把进程插入到合适的位置,就绪队列按优先级由高到低的顺序排列*/
void InsertPriority(PCB *q)
{
PCB *pre,*p;
int flag=1;
pre=NULL;
p=ready;
while(p!=NULL && flag)
{
if(p->prio>q->prio)
{
pre=p;
p=p->next;
}
else
flag=0;
}
if(pre==NULL)
{
q->next=ready;
ready=q;
}
else
{
pre->next=q;
q->next=p;
}
}
/*时间片轮转:把结点插入到就绪队列的末尾*/
void InsertSlot(PCB *q)
{
PCB *pre,*p;
pre=NULL;
p=ready;
while(p!=NULL)
{
pre=p;
p=p->next;
}
pre->next=q;
q->next=NULL; /*由于插入到队列的末尾,所以必须要使其的下一个结点为空值*/
}
/*打印一个信息*/
void PrintOneProcess(int select,PCB *q)
{
if(select==1)
printf("\t\t %-10s%-10d%-10d%c\n",q->name,q->cputime,q->needtime,q->state);
else if(select==2)
printf("\t\t %-10s%-10d%-10d%-10d%c\n",q->name,q->cputime,q->needtime,q->prio,q->state);
else if(select==3)
printf("\t\t %-10s%-10d%-10d%-10d%-10d%c\n",q->name,q->cputime,q->needtime,q->count,q->round,q->state);
}
/*将所有的进程打印出来,按运行,就绪,完成顺序打印*/
void PrintAllProcess(int select)
{
PCB *p;
if(run!=NULL)
PrintOneProcess(select,run);
p=ready;
while(p!=NULL)
{
PrintOneProcess(select,p);
p=p->next;
}
p=finish;
while(p!=NULL)
{
PrintOneProcess(select,p);
p=p->next;
}
}
/*把就绪队列的第一个进程调入运行*/
void FirstIn()
{
run=ready;
ready=ready->next;
run->state='R';
}
/*先进先出调度策略*/
void FIFODo(int select)
{
while(run!=NULL)
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
if(run->needtime==0) //进程执行结束
{
printf("\n\t\t name cputime needtime state\n");
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready!=NULL)
FirstIn();
PrintAllProcess(1);
}
}
}
/*优先级算法*/
void PriorityDo(int select)
{
while(run!=NULL)
{
printf("\n\t\t name cputime needtime prio state\n");
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->prio=run->prio-3;
if(run->needtime==0)
{
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready!=NULL)
FirstIn();
}
else if((ready!=NULL) && (run->prio < ready->prio))
{
run->state='W';
InsertPriority(run);
FirstIn();
}
PrintAllProcess(select);
}
}
/*时间片轮转算法*/
void SlotDo(int select)
{
while(run!=NULL)
{
printf("\n\t\t name cputime needtime count slot state\n");
run->count=run->count+1;
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
if(run->needtime==0) /*运行完成时*/
{
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready!=NULL)
FirstIn(); //就绪队列不为空,将就绪队列的第一个进程投入运行
}
else if(run->count==run->round) /*时间片已经到了,还未运行完成*/
{
run->count=0; //时间片
if(ready!=NULL)
{
run->state='W';
InsertSlot(run);
FirstIn();
}
}
PrintAllProcess(select); //打印本次的所有记录
}
}
void Quit()
{
char ch;
clrscr();
gotoxy(10,5);
printf("==========================================================\n\n");
printf(" Thank you for you using\n\n");
gotoxy(10,9);
printf("==========================================================\n\n");
gotoxy(13,15);
getchar();
printf("\n\t\tDo you really want to quit(y/Y or n/N):");
scanf("%c",&ch);
if(ch=='y' || ch=='Y')
{
printf("\n\t\t按任意键退出系统...");
getchar();
exit(0);
}
}
2. 什么是优先级轮转调度算法支持处理机抢占吗
我想估计跟多级反馈队列算法(Round Robin with Multiple Feedback)有点相似
多级反馈队列算法时间片轮转算法和优先级算法的综合和发展。
优点:
² 为提高系统吞吐量和缩短平均周转时间而照顾短进程。
² 为获得较好的I/O设备利用率和缩短响应时间而照顾I/O型进程。
² 不必估计进程的执行时间,动态调节。
1. 多级反馈队列算法
² 设置多个就绪队列,分别赋予不同的优先级,如逐级降低,队列1的优先级最高。每个队列执行时间片的长度也不同,规定优先级越低则时间片越长,如逐级加倍。
² 新进程进入内存后,先投入队列1的末尾,按FCFS算法调度;若按队列1一个时间片未能执行完,则降低投入到队列2的末尾,同样按FCFS算法调度;如此下去,降低到最后的队列,则按“时间片轮转”算法调度直到完成。
² 仅当较高优先级的队列为空,才调度较低优先级的队列中的进程执行。如果进程执行时有新进程进入较高优先级的队列,则抢先执行新进程,并把被抢先的进程投入原队列的末尾。
3. 动态高优先权优先调度算法
动态高优先权优先调度算法:
动态优先权是指,在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。例如,我们可以规定,在就绪队列中的进程,随其等待时间的增长,其优先权以速率a提高。若所有的进程都具有相同的优先权初值,则显然是最先进入就绪队列的进程,将因其动态优先权变得最高而优先获得处理机,此即FCFS算法。若所有的就绪进程具有各不相同的优先权初值,那么,对于优先权初值低的进程,在等待了足够的时间后,其优先权便可能升为最高,从而可以获得处理机。当采用抢占式优先权调度算法时,如果再规定当前进程的优先权以速率b下降,则可防止一个长作业长期地垄断处理机。
算法代码模拟实现:
#include<stdio.h>
#include<stdlib.h>
#defineN6
//待插入就绪队列的进程数据
intid[N]={0,1,
2,3,4,
5};
intpriority[N]={9,38,17,
2,7,18};
intcpuTime[N]={0,
0,0,0,
0,0};
intallTime[N]={3,
2,3,6,
1,3};
//********************************
//
//模拟进程/PCB数据结构
//
//********************************
//
枚举进程的状态:就绪、执行、阻塞、完成
enumSTATE{Ready,Run,Block,Finish
};
//建立PCB结构体
structPCB{
intid;//标志数
intpriority;//优先数
intcpuTime;//
已占CPU时间
intallTime;//
还需占CPU时间
intblockTime;//已被阻塞的时间
STATEstate;//
进程状态
PCB*pre;//
PCB的前指针
PCB*nxt;//
PCB的后指针
};
//********************************
//
//模拟进程队列
//
//********************************
//进程入列
voidqueQush(PCB*process,PCB
*queHead)
{
process->pre=NULL;
process->nxt=
queHead->nxt;
if(queHead->nxt!=NULL){
//非第一个入列
queHead->nxt->pre=
process;
}
queHead->nxt=process;
}
//进程出列
voidquePop(PCB*process,PCB
*queHead)
{
if(process->pre!=NULL){
//不是头节点
process->pre->nxt=
process->nxt;
}
else{
queHead->nxt=
process->nxt;
}
if(process->nxt!=NULL){
//不是尾节点
process->nxt->pre=
process->pre;
}
//
清空进程指针
process->pre=process->nxt=
NULL;
}
//查看队列里进程的信息
voidqueWalk(PCB*queHead)
{
PCB*pro=queHead->nxt;
if(pro==NULL){
printf("(无进程) ");
return;
}
while(pro!=NULL)
{
printf("id:%d,
pri:%d,alltime:%d ",
pro->id,
pro->priority,
pro->allTime);
pro=
pro->nxt;
}
}
//********************************
//
//模拟就绪队列
//
//********************************
intreadyQueNum;//就绪队列的进程数量
PCBreadyQueHead;//
就绪队列的头部
PCB*readyMaxProcess;//就绪队列中优先级最高的进程
//进程插入到就绪队列
voidreadyQueQush(PCB
*process)
{
readyQueNum++;
process->state=Ready;
queQush(process,&readyQueHead);
}
//优先级最高的进程出列
PCB*readyQuePop()
{
readyQueNum--;
quePop(readyMaxProcess,
&readyQueHead);
returnreadyMaxProcess;
}
//每个时间片,更新就绪队列里进程的信息
voidreadyQueUpdate()
{
intmaxPriority=-1;
PCB*pro=readyQueHead.nxt;
if(pro==NULL){
//就绪队列没有进程
readyMaxProcess=
NULL;
return;
}
while(pro!=NULL)
{
pro->priority
++;
if(pro->priority>maxPriority)
{
maxPriority=
pro->priority;
readyMaxProcess=pro;
}
pro=
pro->nxt;
}
}
//返回就绪队列最高优先级的值
intreadyMaxPriority()
{
returnreadyMaxProcess->priority;
}
//查看就绪队列里进程的信息
voidreadyQueWalk()
{
printf("就绪队列里的进程信息为: ");
queWalk(&readyQueHead);
}
//********************************
//
//模拟阻塞队列
//
//********************************
#defineEndBlockTime3
//进程最长被阻塞时间
intblockQueNum;//阻塞队列的进程数量
PCBblockQueHead;//
阻塞队列的头部
PCB*blockMaxProcess;//阻塞队列中优先级最高的进程
//进程插入到阻塞队列
voidblockQueQush(PCB
*process)
{
blockQueNum++;
process->blockTime=0;
process->state=Block;
queQush(process,&blockQueHead);
}
//优先级最高的进程出列
PCB*blockQuePop()
{
blockQueNum--;
quePop(blockMaxProcess,
&blockQueHead);
returnblockMaxProcess;
}
//每个时间片,更新阻塞队列里进程的信息
voidblockQueUpdate()
{
intmaxPriority=-1;
PCB*pro=blockQueHead.nxt;
while(pro!=NULL)
{
pro->blockTime
++;
if(pro->blockTime>=EndBlockTime)
{
PCB*process=pro;
pro=pro->nxt;
//阻塞时间到,调入就绪队列
blockQueNum--;
quePop(process,
&blockQueHead);
readyQueQush(process);
}else
if(pro->priority>maxPriority)
{
//更新阻塞队列里优先级最高的进程指针
maxPriority=
pro->priority;
blockMaxProcess=pro;
pro=pro->nxt;
}
}
}
//查看阻塞队列里进程的信息
voidblockQueWalk()
{
printf("阻塞队列里的进程信息为: ");
queWalk(&blockQueHead);
}
//********************************
//
//模拟动态优先权的进程调度
//
//********************************
//初始化数据
voidinitData()
{
//
初始化就绪队列和阻塞队列
readyQueNum=blockQueNum=0;
readyMaxProcess=blockMaxProcess=NULL;
readyQueHead.pre=readyQueHead.nxt=NULL;
blockQueHead.pre=blockQueHead.nxt=NULL;
//
初始化进程进入就绪队列
inti,maxPriority=-1;
for(i=0;i<N;i
++)
{
//分配一个PCB的内存空间
PCB*pro=(PCB
*)malloc(sizeof(PCB));
//给当前的PCB赋值
pro->id
=id[i];
pro->priority
=priority[i];
pro->cpuTime
=cpuTime[i];
pro->allTime
=allTime[i];
pro->blockTime
=0;
if(pro->allTime>0){
//插入到就绪队列中
readyQueQush(pro);
//更新就绪队列优先级最高的进程指针
if(pro->priority>
maxPriority){
maxPriority=pro->priority;
readyMaxProcess=pro;
}
}
}
}
//模拟cpu执行1个时间片的操作
voidcpuWord(PCB
*cpuProcess)
{
cpuProcess->priority-=3;
if(cpuProcess->priority<0)
{
cpuProcess->priority=0;
}
cpuProcess->cpuTime++;
cpuProcess->allTime--;
//
显示正执行进程的信息:
printf("CPU正执行的进程信息为: ");
printf("id:M,pri:M,
alltime:M ",
cpuProcess->id,
cpuProcess->priority,
cpuProcess->allTime);
}
intmain()
{
inttimeSlice=0;//
模拟时间片
intcpuBusy=0;
//模拟cpu状态
PCB*cpuProcess=NULL;//当前在cpu执行的进程
//
初始化数据
initData();
//
模拟进程调度
while(1)
{
if(readyQueNum==0
&&blockQueNum==0
&&cpuBusy==0){
//就绪队列、阻塞队列和cpu无进程,退出
break;
}
//printf(" %d%d",
readyQueNum,blockQueNum);
if(cpuBusy==0)
{
//cpu空闲,选择一个进程进入cpu
if(readyQueNum>0)
{
//
选择绪队列优先级最高的进程
cpuProcess
=readyQuePop();
}else{
//
就绪队列没有进程,改为选择阻塞队列优先级最高的进程
cpuProcess
=blockQuePop();
}
cpuProcess->cpuTime=
0;
cpuProcess->state=
Run;
cpuBusy=1;
}
timeSlice++;
printf(" 第%d个时间片后: ",
timeSlice);
//
模拟cpu执行1个时间片的操作
cpuWord(cpuProcess);
if(cpuProcess->allTime==0){
cpuProcess->state=
Finish;
//释放已完成进程的PCB
free(cpuProcess);
cpuBusy=0;
}
//
更新就绪队列和阻塞队列里的进程信息
blockQueUpdate();
readyQueUpdate();
//
查看就绪队列和阻塞队列的进程信息
readyQueWalk();
blockQueWalk();
if(cpuBusy==1
&&readyQueNum>0
&&
cpuProcess->priority
<readyMaxPriority()){
//需抢占cpu,当前执行的进程调入阻塞队列
blockQueQush(cpuProcess);
cpuProcess=readyQuePop();
}
}
printf(" 模拟进程调度算法结束 ");
return0;
}
4. 1.选用优先级算法和时间片轮转算法模拟实现进程调度算法
我们考试上交的 能运行
#define MAX 100
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int b;//存放进程本次结束时的时间
void main()
{
int i,N,t,k;
int a[MAX];//存放进程的剩余时间
int cnt[MAX];//存放进程调度次数
printf("请输入进程数N:");
scanf("%d",&N);
printf("\n请输入时间片t大小:");
scanf("%d",&t);
printf("\n请依次输入各个进程的服务时间");
for(i=0;i<N;i++)
{
scanf("%d",&a[i]);
cnt[i]=0;
}
printf("被调度进程\t进程调度次数 \t本次运行时间结果\t剩余时间\n");
k=1;
while(k)
{
for(i=0;i<N;i++)
{
if(a[i]!=0)
if(a[i]>=t)
{
a[i]-=t;
b+=t;
cnt[i]=cnt[i]+1;
printf("\n\t%d\t\t%d\t\t%d\t\t%d",i+1,cnt[i],b,a[i]);
}
else
{
b=b+a[i];
cnt[i]=cnt[i]+1;
a[i]=0;
printf("\n\t%d\t\t%d\t\t%d\t\t%d",i+1,cnt[i],b,a[i]);
}
else continue;
}
for(i=0;i<N;i++)
if(a[i]!=0)
{ k=1;break;}
else continue;
if(i>=N)
k=0;
}
printf("\n");
printf("进程全部运行完成!");
printf("\n");
}
5. 静态抢占式优先级调度算法是如何进行的
按照优先级值的大小进行调度,选择优先级值大的作业优先调度。抢占式是指如果进入的作业的优先级数大于当前正在执行的作业的优先级数,就执行进入的作业,抢占了当前正在执行的作业的资源。
按照到达时间将作业放入就绪队列,当前作业执行过程中有作业进入,根据作业的优先级值进行判断,如果进入的作业的优先级值小于或等于当前执行的作业的优先级值,继续执行当前作业;如果进入的作业的优先级值大于当前执行的作业的优先级值,将资源给进入的作业,当前的作业就放入就绪队列队尾,此时还需要的服务时间为原服务时间-进入的作业的到达时间。之后,每到达一个作业就与当前执行的作业进行优先级值比较,优先级值大的优先执行。当当前执行的作业执行结束后,比较就绪队列中的作业的优先级值,优先级值大的优先执行。如此执行,直到就绪队列为空,结束调度。
6. 基于优先级的调度算法有哪两种
静态优先级和动态优先级
7. 优先级调度算法如何用JAVA实现
在多线程时,可以手动去设置每个线程的优先级setPriority(int newPriority)
更改线程的优先级。
8. 作业调度算法中HPF算法的动态优先级如何设定优先级标准
方法如下:
php">#include"stdio.h"
#include<STDLIB.H>
#include<CONIO.H>
#definegetpch(type)(type*)malloc(sizeof(type))
#defineNULL0
structpcb{/*定义进程控制块PCB*/
charname[10];
charstate;
intsuper;
intntime;
intrtime;
structpcb*link;
}*ready=NULL,*p;
typedefstructpcbPCB;
sort()/*建立对进程进行优先级排列函数*/
{
PCB*first,*second;
intinsert=0;
if((ready==NULL)||((p->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;
second=second->link;
}
}
if(insert==0)first->link=p;
}
}
input()/*建立进程控制块函数*/
{
inti,num;
//clrscr();/*清屏*/
printf(" 请输入进程号?");
scanf("%d",&num);
for(i=0;i<NUM;I++)scanf(?%s?,p-输入进程名:?);printf(? p="getpch(PCB);"进程号No.%d: ?,i);{>name);
printf(" 输入进程优先数:");
scanf("%d",&p->super);
printf(" 输入进程运行时间:");
scanf("%d",&p->ntime);
printf(" ");
p->rtime=0;p->state='w';
p->link=NULL;
sort();/*调用sort函数*/
}
}
intspace()
{
intl=0;PCB*pr=ready;
while(pr!=NULL)
{
l++;
pr=pr->link;
}
return(l);
}
disp(PCB*pr)/*建立进程显示函数,用于显示当前进程*/
{
printf(" qname state super ndtime runtime ");
printf("|%s ",pr->name);
printf("|%c ",pr->state);
printf("|%d ",pr->super);
printf("|%d ",pr->ntime);
printf("|%d ",pr->rtime);
printf(" ");
}
check()/*建立进程查看函数*/
{
PCB*pr;
printf(" ****当前正在运行的进程是:%s",p->name);/*显示当前运行进程*/
disp(p);
pr=ready;
printf(" ****当前就绪队列状态为: ");/*显示就绪队列状态*/
while(pr!=NULL)
{
disp(pr);
pr=pr->link;
}
}
destroy()/*建立进程撤消函数(进程运行结束,撤消进程)*/
{
printf(" 进程[%s]已完成. ",p->name);
free(p);
}
running()/*建立进程就绪函数(进程运行时间到,置就绪状态*/
{
(p->rtime)++;
if(p->rtime==p->ntime)
destroy();/*调用destroy函数*/
else
{
(p->super)--;
p->state='w';
sort();/*调用sort函数*/
}
}
main()/*主函数*/
{
intlen,h=0;
charch;
input();
len=space();
while((len!=0)&&(ready!=NULL))
{
ch=getchar();
h++;
printf(" Theexecutenumber:%d ",h);
p=ready;
ready=p->link;
p->link=NULL;
p->state='R';
check();
running();
printf(" 按任一键继续......");
ch=getchar();
}
printf(" 进程已经完成. ");
ch=getchar();
}
9. 先来先服务调度算法。 优先级调度算法。 短作业优先调度算法 轮转调度算法 响应比高优先调度算法
你试一下
#include<stdio.h>
//using namespace std;
#define MAX 10
struct task_struct
{
char name[10]; /*进程名称*/
int number; /*进程编号*/
float come_time; /*到达时间*/
float run_begin_time; /*开始运行时间*/
float run_time; /*运行时间*/
float run_end_time; /*运行结束时间*/
int priority; /*优先级*/
int order; /*运行次序*/
int run_flag; /*调度标志*/
}tasks[MAX];
int counter; /*实际进程个数*/
int fcfs(); /*先来先服务*/
int ps(); /*优先级调度*/
int sjf(); /*短作业优先*/
int hrrn(); /*响应比高优先*/
int pinput(); /*进程参数输入*/
int poutput(); /*调度结果输出*/
void main()
{ int option;
pinput();
printf("请选择调度算法(0~4):\n");
printf("1.先来先服务\n");
printf("2.优先级调度\n");
printf(" 3.短作业优先\n");
printf(" 4.响应比高优先\n");
printf(" 0.退出\n");
scanf("%d",&option);
switch (option)
{case 0:
printf("运行结束。\n");
break;
case 1:
printf("对进程按先来先服务调度。\n\n");
fcfs();
poutput();
break;
case 2:
printf("对进程按优先级调度。\n\n");
ps();
poutput();
break;
case 3:
printf("对进程按短作业优先调度。\n\n");
sjf();
poutput();
break;
case 4:
printf("对进程按响应比高优先调度。\n\n");
hrrn();
poutput();
break;
}
}
int fcfs() /*先来先服务*/
{
float time_temp=0;
inti;
intnumber_schel;
time_temp=tasks[0].come_time;
for(i=0;i<counter;i++)
{
tasks[i].run_begin_time=time_temp;
tasks[i].run_end_time=tasks[i].run_begin_time+tasks[i].run_time;
tasks[i].run_flag=1;
time_temp=tasks[i].run_end_time;
number_schel=i;
tasks[number_schel].order=i+1;
}
return 0;
}
int ps() /*优先级调度*/
{
float temp_time=0;
inti=0,j;
intnumber_schel,temp_counter;
intmax_priority;
max_priority=tasks[i].priority;
j=1;
while((j<counter)&&(tasks[i].come_time==tasks[j].come_time))
{
if (tasks[j].priority>tasks[i].priority)
{
max_priority=tasks[j].priority;
i=j;
}
j++;
} /*查找第一个被调度的进程*/
/*对第一个被调度的进程求相应的参数*/
number_schel=i;
tasks[number_schel].run_begin_time=tasks[number_schel].come_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].order=1;
temp_counter=1;
while (temp_counter<counter)
{
max_priority=0;
for(j=0;j<counter;j++)
{if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if (tasks[j].priority>max_priority)
{
max_priority=tasks[j].priority;
number_schel=j;
}
} /*查找下一个被调度的进程*/
/*对找到的下一个被调度的进程求相应的参数*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
temp_counter++;
tasks[number_schel].order=temp_counter;
}return 0;
}
int sjf() /*短作业优先*/
{
float temp_time=0;
inti=0,j;
intnumber_schel,temp_counter;
float run_time;
run_time=tasks[i].run_time;
j=1;
while((j<counter)&&(tasks[i].come_time==tasks[j].come_time))
{
if (tasks[j].run_time<tasks[i].run_time)
{
run_time=tasks[j].run_time;
i=j;
}
j++;
} /*查找第一个被调度的进程*/
/*对第一个被调度的进程求相应的参数*/
number_schel=i;
tasks[number_schel].run_begin_time=tasks[number_schel].come_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].order=1;
temp_counter=1;
while (temp_counter<counter)
{
for(j=0;j<counter;j++)
{
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
{run_time=tasks[j].run_time;number_schel=j;break;}
}
for(j=0;j<counter;j++)
{if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if(tasks[j].run_time<run_time)
{run_time=tasks[j].run_time;
number_schel=j;
}
}
/*查找下一个被调度的进程*/
/*对找到的下一个被调度的进程求相应的参数*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
tasks[number_schel].run_flag=1;
temp_time=tasks[number_schel].run_end_time;
temp_counter++;
tasks[number_schel].order=temp_counter;
}return 0;
}
int hrrn() /*响应比高优先*/
{ int j,number_schel,temp_counter;
float temp_time,respond_rate,max_respond_rate;
/*第一个进程被调度*/
tasks[0].run_begin_time=tasks[0].come_time;
tasks[0].run_end_time=tasks[0].run_begin_time+tasks[0].run_time;
temp_time=tasks[0].run_end_time;
tasks[0].run_flag=1;
tasks[0].order=1;
temp_counter=1;
/*调度其他进程*/
while(temp_counter<counter)
{
max_respond_rate=0;
for(j=1;j<counter;j++)
{
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
{respond_rate=(temp_time-tasks[j].come_time)/tasks[j].run_time;
if (respond_rate>max_respond_rate)
{
max_respond_rate=respond_rate;
number_schel=j;
}
}
} /*找响应比高的进程*/
tasks[number_schel].run_begin_time=temp_time;
tasks[number_schel].run_end_time=tasks[number_schel].run_begin_time+tasks[number_schel].run_time;
temp_time=tasks[number_schel].run_end_time;
tasks[number_schel].run_flag=1;
temp_counter+=1;
tasks[number_schel].order=temp_counter;
}
return 0;
}
int pinput() /*进程参数输入*/
{ int i;
printf("please input the processcounter:\n");
scanf("%d",&counter);
for(i=0;i<counter;i++)
{printf("******************************************\n");
printf("please input the process of %d th :\n",i+1);
printf("please input the name:\n");
scanf("%s",tasks[i].name);
printf("please input the number:\n");
scanf("%d",&tasks[i].number);
printf("please input the come_time:\n");
scanf("%f",&tasks[i].come_time);
printf("please input the run_time:\n");
scanf("%f",&tasks[i].run_time);
printf("please input the priority:\n");
scanf("%d",&tasks[i].priority);
tasks[i].run_begin_time=0;
tasks[i].run_end_time=0;
tasks[i].order=0;
tasks[i].run_flag=0;
}
return 0;
}
int poutput() /*调度结果输出*/
{
int i;
float turn_round_time=0,f1,w=0;
printf("name number come_time run_timerun_begin_time run_end_time priority order turn_round_time\n");
for(i=0;i<counter;i++)
{
f1=tasks[i].run_end_time-tasks[i].come_time;
turn_round_time+=f1;
w+=(f1/tasks[i].run_time);
printf(" %s, %d, %5.3f, %5.3f, %5.3f, %5.3f, %d, %d,%5.3f\n",tasks[i].name,tasks[i].number,tasks[i].come_time,tasks[i].run_time,tasks[i].run_begin_time,tasks[i].run_end_time,tasks[i].priority,tasks[i].order,f1);
}
printf("average_turn_round_timer=%5.2f\n",turn_round_time/counter);
printf("weight_average_turn_round_timer=%5.2f\n",w/counter);
return 0;
}
10. 时间片轮转算法和优先级调度算法 C语言模拟实现
一、目的和要求
进程调度是处理机管理的核心内容。本实验要求用高级语言编写模拟进程调度程序,以便加深理解有关进程控制快、进程队列等概念,并体会和了解优先数算法和时间片轮转算法的具体实施办法。
二、实验内容
1.设计进程控制块PCB的结构,通常应包括如下信息:
进程名、进程优先数(或轮转时间片数)、进程已占用的CPU时间、进程到完成还需要的时间、进程的状态、当前队列指针等。
2.编写两种调度算法程序:
优先数调度算法程序
循环轮转调度算法程序
3.按要求输出结果。
三、提示和说明
分别用两种调度算法对伍个进程进行调度。每个进程可有三种状态;执行状态(RUN)、就绪状态(READY,包括等待状态)和完成状态(FINISH),并假定初始状态为就绪状态。
(一)进程控制块结构如下:
NAME——进程标示符
PRIO/ROUND——进程优先数/进程每次轮转的时间片数(设为常数2)
CPUTIME——进程累计占用CPU的时间片数
NEEDTIME——进程到完成还需要的时间片数
STATE——进程状态
NEXT——链指针
注:
1.为了便于处理,程序中进程的的运行时间以时间片为单位进行计算;
2.各进程的优先数或轮转时间片数,以及进程运行时间片数的初值,均由用户在程序运行时给定。
(二)进程的就绪态和等待态均为链表结构,共有四个指针如下:
RUN——当前运行进程指针
READY——就需队列头指针
TAIL——就需队列尾指针
FINISH——完成队列头指针
(三)程序说明
1. 在优先数算法中,进程优先数的初值设为:
50-NEEDTIME
每执行一次,优先数减1,CPU时间片数加1,进程还需要的时间片数减1。
在轮转法中,采用固定时间片单位(两个时间片为一个单位),进程每轮转一次,CPU时间片数加2,进程还需要的时间片数减2,并退出CPU,排到就绪队列尾,等待下一次调度。
2. 程序的模块结构提示如下:
整个程序可由主程序和如下7个过程组成:
(1)INSERT1——在优先数算法中,将尚未完成的PCB按优先数顺序插入到就绪队列中;
(2)INSERT2——在轮转法中,将执行了一个时间片单位(为2),但尚未完成的进程的PCB,插到就绪队列的队尾;
(3)FIRSTIN——调度就绪队列的第一个进程投入运行;
(4)PRINT——显示每执行一次后所有进程的状态及有关信息。
(5)CREATE——创建新进程,并将它的PCB插入就绪队列;
(6)PRISCH——按优先数算法调度进程;
(7)ROUNDSCH——按时间片轮转法调度进程。
主程序定义PCB结构和其他有关变量。
(四)运行和显示
程序开始运行后,首先提示:请用户选择算法,输入进程名和相应的NEEDTIME值。
每次显示结果均为如下5个字段:
name cputime needtime priority state
注:
1.在state字段中,"R"代表执行态,"W"代表就绪(等待)态,"F"代表完成态。
2.应先显示"R"态的,再显示"W"态的,再显示"F"态的。
3.在"W"态中,以优先数高低或轮转顺序排队;在"F"态中,以完成先后顺序排队。
view plain to clipboardprint?
/*
操作系统实验之时间片轮转算法和优先级调度算法
By Visual C++ 6.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char name[20]; /*进程的名字*/
int prio; /*进程的优先级*/
int round; /*分配CPU的时间片*/
int cputime; /*CPU执行时间*/
int needtime; /*进程执行所需要的时间*/
char state; /*进程的状态,W——就绪态,R——执行态,F——完成态*/
int count; /*记录执行的次数*/
struct node *next; /*链表指针*/
}PCB;
PCB *ready=NULL,*run=NULL,*finish=NULL; /*定义三个队列,就绪队列,执行队列和完成队列*/
int num;
void GetFirst(); /*从就绪队列取得第一个节点*/
void Output(); /*输出队列信息*/
void InsertPrio(PCB *in); /*创建优先级队列,规定优先数越小,优先级越高*/
void InsertTime(PCB *in); /*时间片队列*/
void InsertFinish(PCB *in); /*时间片队列*/
void PrioCreate(); /*优先级输入函数*/
void TimeCreate(); /*时间片输入函数*/
void Priority(); /*按照优先级调度*/
void RoundRun(); /*时间片轮转调度*/
int main(void)
{
char chose;
printf("请输入要创建的进程数目:\n");
scanf("%d",&num);
getchar();
printf("输入进程的调度方法:(P/R)\n");
scanf("%c",&chose);
switch(chose)
{
case 'P':
case 'p':
PrioCreate();
Priority();
break;
case 'R':
case 'r':
TimeCreate();
RoundRun();
break;
default:break;
}
Output();
return 0;
}
void GetFirst() /*取得第一个就绪队列节点*/
{
run = ready;
if(ready!=NULL)
{
run ->state = 'R';
ready = ready ->next;
run ->next = NULL;
}
}
void Output() /*输出队列信息*/
{
PCB *p;
p = ready;
printf("进程名\t优先级\t轮数\tcpu时间\t需要时间\t进程状态\t计数器\n");
while(p!=NULL)
{
printf("%s\t%d\t%d\t%d\t%d\t\t%c\t\t%d\n",p->name,p->prio,p->round,p->cputime,p->needtime,p->state,p->count);
p = p->next;
}
p = finish;
while(p!=NULL)
{
printf("%s\t%d\t%d\t%d\t%d\t\t%c\t\t%d\n",p->name,p->prio,p->round,p->cputime,p->needtime,p->state,p->count);
p = p->next;
}
p = run;
while(p!=NULL)
{
printf("%s\t%d\t%d\t%d\t%d\t\t%c\t\t%d\n",p->name,p->prio,p->round,p->cputime,p->needtime,p->state,p->count);
p = p->next;
}
}
void InsertPrio(PCB *in) /*创建优先级队列,规定优先数越小,优先级越低*/
{
PCB *fst,*nxt;
fst = nxt = ready;
if(ready == NULL) /*如果队列为空,则为第一个元素*/
{
in->next = ready;
ready = in;
}
else /*查到合适的位置进行插入*/
{
if(in ->prio >= fst ->prio) /*比第一个还要大,则插入到队头*/
{
in->next = ready;
ready = in;
}
else
{
while(fst->next != NULL) /*移动指针查找第一个别它小的元素的位置进行插入*/
{
nxt = fst;
fst = fst->next;
}
if(fst ->next == NULL) /*已经搜索到队尾,则其优先级数最小,将其插入到队尾即可*/
{
in ->next = fst ->next;
fst ->next = in;
}
else /*插入到队列中*/
{
nxt = in;
in ->next = fst;
}
}
}
}
void InsertTime(PCB *in) /*将进程插入到就绪队列尾部*/
{
PCB *fst;
fst = ready;
if(ready == NULL)
{
in->next = ready;
ready = in;
}
else
{
while(fst->next != NULL)
{
fst = fst->next;
}
in ->next = fst ->next;
fst ->next = in;
}
}
void InsertFinish(PCB *in) /*将进程插入到完成队列尾部*/
{
PCB *fst;
fst = finish;
if(finish == NULL)
{
in->next = finish;
finish = in;
}
else
{
while(fst->next != NULL)
{
fst = fst->next;
}
in ->next = fst ->next;
fst ->next = in;
}
}
void PrioCreate() /*优先级调度输入函数*/
{
PCB *tmp;
int i;
printf("输入进程名字和进程所需时间:\n");
for(i = 0;i < num; i++)
{
if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL)
{
perror("malloc");
exit(1);
}
scanf("%s",tmp->name);
getchar(); /*吸收回车符号*/
scanf("%d",&(tmp->needtime));
tmp ->cputime = 0;
tmp ->state ='W';
tmp ->prio = 50 - tmp->needtime; /*设置其优先级,需要的时间越多,优先级越低*/
tmp ->round = 0;
tmp ->count = 0;
InsertPrio(tmp); /*按照优先级从高到低,插入到就绪队列*/
}
}
void TimeCreate() /*时间片输入函数*/
{
PCB *tmp;
int i;
printf("输入进程名字和进程时间片所需时间:\n");
for(i = 0;i < num; i++)
{
if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL)
{
perror("malloc");
exit(1);
}
scanf("%s",tmp->name);
getchar();
scanf("%d",&(tmp->needtime));
tmp ->cputime = 0;
tmp ->state ='W';
tmp ->prio = 0;
tmp ->round = 2; /*假设每个进程所分配的时间片是2*/
tmp ->count = 0;
InsertTime(tmp);
}
}
void Priority() /*按照优先级调度,每次执行一个时间片*/
{
int flag = 1;
GetFirst();
while(run != NULL) /*当就绪队列不为空时,则调度进程如执行队列执行*/
{
Output(); /*输出每次调度过程中各个节点的状态*/
while(flag)
{
run->prio -= 3; /*优先级减去三*/
run->cputime++; /*CPU时间片加一*/
run->needtime--;/*进程执行完成的剩余时间减一*/
if(run->needtime == 0)/*如果进程执行完毕,将进程状态置为F,将其插入到完成队列*/
{
run ->state = 'F';
run->count++; /*进程执行的次数加一*/
InsertFinish(run);
flag = 0;
}
else /*将进程状态置为W,入就绪队列*/
{
run->state = 'W';
run->count++; /*进程执行的次数加一*/
InsertTime(run);
flag = 0;
}
}
flag = 1;
GetFirst(); /*继续取就绪队列队头进程进入执行队列*/
}
}
void RoundRun() /*时间片轮转调度算法*/
{
int flag = 1;
GetFirst();
while(run != NULL)
{
Output();
while(flag)
{
run->count++;
run->cputime++;
run->needtime--;
if(run->needtime == 0) /*进程执行完毕*/
{
run ->state = 'F';
InsertFinish(run);
flag = 0;
}
else if(run->count == run->round)/*时间片用完*/
{
run->state = 'W';
run->count = 0; /*计数器清零,为下次做准备*/
InsertTime(run);
flag = 0;
}
}
flag = 1;
GetFirst();
}