操作系统,进程调度之时间片轮转算法
命名是中英混名(英语不好),第一次分享代码,如果有不好的地方还请指出。
typedef struct PCB
{
char Name;//进程名
int Arrivetime;//到达时间
int Servertime;//服务时间
int Front;//优先级
int Starttime;//开始时间
int Finishtime;//完成时间
float Wholetime;//周转时间
float Valuewholetime;//带权周转时间
int Ago;//是否被访问标记
struct PCB *next;
int Shenyutime;//剩余时间
int Zdtime;//中断时间
}_PCB;
_PCB *head;
_PCB *creat()//创建并输入链表
{
char c;
int a=0, b=0,yxj=0;
PCB *p1,*p2;
head= (PCB*)malloc(LEN);
head->next=NULL;
p1 = head;
while (true)
{
p2 = (PCB*)malloc(LEN);
printf("进程名 到达时间 服务时间 优先级(全为0结束)\n");
scanf_s("%c %d %d %d", &c,sizeof(c),&a, &b,&yxj);
getchar();
if (a == 0 && b == 0) {
p2->next = NULL;
break;
}//其实中间两个为0就结束了
else {//各种初始化和录入信息
p2->Ago = 0;
p2->Starttime = 0;
p2->Finishtime = 0;
p2->Front = yxj;
p2->Name = c;
p2->Arrivetime = a;
p2->Zdtime = a;
p2->Servertime = b;
p2->Shenyutime = b;
p2->next = NULL;
p1->next = p2;
p1 = p2;
}
}
return head;
}
void Sort(_PCB *&l) { //采用头插法,使用先到先服务排序
_PCB* p = l->next, * pre;
_PCB* r = p->next;
p->next = NULL;
p = r;
while (p != NULL) {
r = p->next;
pre = l;
while (pre->next != NULL && pre->next->Arrivetime < p->Arrivetime) {
pre = pre->next;
}
p->next = pre->next;
pre->next = p;
p = r;
}
}
_PCB* sjplz(int n,_PCB *l) {
_PCB *h,*a,*b,*c,*d;
h = l;
b = h->next;
a = b;
int p = 0;
b->Starttime = b->Arrivetime;//第一个到达时间就是第一个进程的开始时间
p = b->Arrivetime;
printf("进程\t到达时间\t服务时间\t开始时间\t完成时间\t剩余时间\t执行次数\t当前时间\n");
while (b)
{
c = b->next;
if (b->Starttime == 0 && b->Ago == 0)b->Starttime = p;//判断进程是否执行过,计算进程开始时间
if (b->Shenyutime <= n) {//判断剩余时间
if (b->Ago!=0) {//是否执行过
b->Finishtime = b->Shenyutime + p;
p = p + b->Shenyutime;
b->Shenyutime = 0;
b->Ago++;
printf("%c\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", b->Name, b->Arrivetime, b->Servertime, b->Starttime, b->Finishtime, b->Shenyutime, b->Ago, p);
}else {
if (b->Arrivetime > p ) {
b->Starttime = b->Arrivetime;//如果进程开始前存在系统空闲,开始时间即该进程到达时间
}
else
{
b->Starttime = p;//开始时间是当前系统时间
}
b->Finishtime = b->Shenyutime + p;//计算完成时间
p = p + b->Shenyutime;
b->Ago++;
b->Shenyutime = 0;
printf("%c\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", b->Name, b->Arrivetime, b->Servertime, b->Starttime, b->Finishtime, b->Shenyutime, b->Ago, p);
}
}else {
b->Shenyutime = b->Shenyutime - n;//一次时间片内未完
p = p + n;
b->Zdtime = p;//记录中断时间
b->Ago++;
printf("%c\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", b->Name, b->Arrivetime, b->Servertime, b->Starttime, b->Finishtime, b->Shenyutime, b->Ago, p);
if (c!=NULL) {
int i = 0;
int j=0;
while (c)
{
if (c->Arrivetime > p || b->Zdtime > p) {//寻找该进程下一次进入就绪序列的位置
if (i == 0) {
l->next = b->next;
b = l;
j = 1;
break;
}
else
{
l->next = b->next;
a->next = b;
b->next = c;
b = l;
j = 1;
}
break;
}
a = c;
c = c->next;
i++;
}
if (j == 0) {//未找到比该进程更晚进入的进程,接入链尾
l->next = b->next;
a->next = b;
b->next = NULL;
b = l;
}
}else {//就绪队列仅剩一个,持续执行该进程直至完成
l->next = b;
b->next = NULL;
b = l;
}
}
d = b;
b = b->next;
}
return l;//传出来的头指针与原链表不同,会丢失数据,但是不影响中间计算过程。
}
int main()
{
_PCB* k;
k = creat();
int s;
Sort(k);
printf("输入时间片长度\n n=");
scanf_s("%d",&s);
k=sjplz(s,k);
return 0;
}
图片: