描述
用于分时系统中的进程调度。每次调度时,总是选择就绪队列的队首进程,让其在CPU上运行一个系统预先设置好的时间片。一个时间片内没有完成运行的进程,返回到绪队列末尾重新排队,等待下一次调度。
算法步骤
1. 假设系统中有n个进程,每个进程有一个进程控制块(PCB)来标识。进程控制块内容包括:进程标识,链接指针,服务时间,到达时间,进程状态。
链接指针:按照进程到达系统的时间将处于就绪状态的进程连接成一个就绪队列。指针指出下一个到达进程的进程控制块地址。最后一个进程的链接指针为NULL。
2.为每个进程任意确定一个到达时间和要求运行时间。
3.设置两个带头结点的队列,一个为就绪队列ready,另一个为进程池队列pool。pool队列中将进程按照到达时间由早到慢排序。
4.若pool和ready中至少一个不为空,则执行下列步骤直到pool和ready都为空
- 若ready不为空,弹出ready队首进程运行,在运行过程中若有其他进 程加入,则将其他进程加入ready队尾。在给定的时间片内,若进程执行完成,则释放进程所占的空间。若未执行完成,将该进程加入ready队尾。打印ready中的进程,执行步骤4
- 若ready为空,以1为时间单位检查pool中是否有进程到达,若有加入ready, 若无,时间加1,继续检查直到有进程到达,然后再次执行步骤4
5.若pool和ready均为空,则进程运行结束。
源代码
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <malloc.h>
typedef struct node
{
char name;//进程标识符
int arrivetime;//到达时间
int servicetime;//服务时间
int lefttime;//还剩运行时间
char state;//进程状态
struct node *next;
}PCB;
PCB* createprocess(int n)//创建进程队列
{
printf("创建进程......\n");
PCB *head=(PCB*)malloc(sizeof(PCB));//工作指针的前一个节点指针
PCB *q=(PCB*)malloc(sizeof(PCB));
//PCB *pnew=malloc(sizeof(PCB));//工作指针
int i;
for(i=0;i<n;i++)
{
PCB *pnew=(PCB*)malloc(sizeof(PCB));//工作指针
if(i==0)
head->next=pnew;
printf("请输入%d个进程的名字,到达时间和服务时间\n",i+1);
getchar();
scanf("%c%d%d",&pnew->name,&pnew->arrivetime,&pnew->servicetime);
pnew->state='R';
pnew->lefttime=pnew->servicetime;
pnew->next=NULL;
q->next=pnew;
q=pnew;
//getchar();
}
q->next=NULL;
q=NULL;
free(q);
return head;
}
PCB* pop(PCB *p)//弹出队首进程
{
PCB *t=(PCB*)malloc(sizeof(PCB));
t=p->next;
p->next=p->next->next;
t->next=NULL;
return t;
}
void push(PCB *p,PCB *t)//将进程t加入p队列中
{
PCB *q=p;
while(q->next)
{
q=q->next;
}
q->next=t;
t->next=NULL;
}
void sortofat(PCB *p,int n)//按照进程到达时间排序
{
PCB *r,*q;
int i,j;
for(i=0;i<n;i++)
{
q=p;
for(j=0;j<n-i-1;j++)
{
r=q->next;
if(r->arrivetime<q->arrivetime)
{
q->next=r->next;
r->next=q;
}
q=q->next;
}
}
}
void runprocess(PCB *p,int n,int round)//运行进程
{
sortofat(p,n);//按照进程到达时间排序
PCB *cur=p;//当前运行进程
PCB *pool=p;//进程池中的队列
PCB *ready=(PCB *)malloc(sizeof(PCB));//就绪队列,含有头结点
ready->next=NULL;
int curtime=0;//当前时间
PCB *s;//用于打印进程队列的进程信息
//寻找第一个可执行进程
while(1)
{
if(pool->next->arrivetime>curtime)
curtime++;
else
{
PCB *temp=pop(pool);
push(ready,temp);
break;
}
}
while(1)
{
//寻找可以调度的进程
if(ready->next)
{
cur=pop(ready);
//打印正在运行的进程信息
printf("正在运行的进程\n");
printf("进程标识 到达时间 服务时间 已运行时间 还剩运行时间\n");
printf("%c \t %d \t %d \t %d \t %d\n",cur->name,cur->arrivetime,cur->servicetime,cur->servicetime-cur->lefttime,cur->lefttime);
//进程运行
int slice=round;
while(cur->lefttime&&slice)
{
slice--;
curtime++;
cur->lefttime--;
if(pool->next&&pool->next->arrivetime<=curtime)
{
PCB * temp=pop(pool);
push(ready,temp);
}
}
//打印当前就绪队列中的进程
printf("进程%c执行一次后就绪队列中的进程\n",cur->name);
printf("此时的时间点为%d\n",curtime);
printf("进程标识 到达时间 服务时间 已运行时间 还剩运行时间\n");
s=ready->next;
//检查当前进程是否运行结束
if(cur->lefttime>0)//进程运行未结束
push(ready,cur);
else//进程运行结束,释放内存
{
cur->state='C';
PCB *temp=cur;
temp=NULL;
free(temp);
cur=NULL;
}
while(s)
{
if( s->arrivetime<=curtime&&s->state=='R')
{ printf("%c \t %d \t %d \t %d \t %d\n",s->name,s->arrivetime,s->servicetime,s->servicetime-s->lefttime,s->lefttime);}
s=s->next;
}
//判断是否所有进程都执行结束
if(pool->next==NULL&&ready->next==NULL)
break;
printf("\n");
}
else//就绪队列为空,进程池不为空
{
while(1)
{
if(pool->arrivetime>curtime)
curtime++;
else
{
PCB *temp=pop(pool);
push(ready,temp);
break;
}
}
}
}
}
int main()
{
int n;
int round;
scanf("%d%d",&n,&round);
PCB *p=createprocess(n);
runprocess(p,n,round);
return 0;
}
运行结果
输入,创建3个进程,时间片为1