一、实验目的:
了解并掌握作业调度的功能,熟悉并掌握各种作业调度算法。
二、实验内容:
模拟实现FCFS/SJF调度。
设置作业体:作业名,作业的到达时间,服务时间,作业状态(W——等待,R——运行,F——完成),作业间的链接指针;
作业初始化:由用户输入作业名、服务时间、到达时间进行初始化,同时,初始化作业的状态为W。
显示函数:在作业调度前、调度中和调度后进行显示。
排序函数:对等待状态的作业按照调度算法排序(不同的调度算法排序方式不同),注意考虑到达时间。
调度函数:每次从等待队列队首调度已到达的适合的作业执行,状态变化。当服务结束时,状态变为F。
删除函数:撤销状态为F的作业。
三、实验代码
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
typedef struct jobInfo *List;
struct jobInfo
{
char name, status;//作业名、状态
int arrival_time, service_time, remaining_time, finish_time, uid;//到达时间、服务时间、剩余服务时间、完成时间
List Next;//下一个作业体
};
List MakeEmpty();//创建空链表
int in_it();//初始化,返回作业总数
void Insert(List L, jobInfo *t, int flag);//插入
void Delete(List L, jobInfo *t);//删除
void solve();
void Show_Before();//初始信息
void Show_Ing();//每个时刻作业的情况
void Show_After();//调度图
List CreateList, WaitList, FinishList;//创建队列、就绪队列、完成队列、
int TotalNum, CurrentTime;//作业总数量、模拟时间片前进
char *record;//每个时间片处理的作业名
int main()
{
CreateList = MakeEmpty();
TotalNum = in_it();
Show_Before();
WaitList = MakeEmpty();
FinishList = MakeEmpty();
printf("过程详情\n");
solve();
// Show_Ing();
Show_After();
return 0;
}
List MakeEmpty()
{
List L;
L = (List)malloc(sizeof(struct jobInfo));
L->Next = NULL;
return L;
}
int in_it()
{
printf("输入格式:”作业名 到达时间 服务时间“,Ctrl+Z结束输入\n");
int n = 0, arrival_time, service_time;
char name;
while(scanf("%c", &name) != EOF)
{
scanf("%d%d", &arrival_time, &service_time);
jobInfo *t;
t = (jobInfo*)malloc(sizeof(struct jobInfo));
t->name = name;
t->arrival_time = arrival_time;
t->remaining_time = service_time;
t->service_time = service_time;
t->finish_time = -1;
t->status = 'W';
t->uid = n;
t->Next = NULL;
Insert(CreateList, t, 1);
n++;
getchar();
}
return n;
}
void Insert(List L, jobInfo *t, int flag)//flag用于不同排序的选择
{
if(L->Next == NULL)//判断空链表
{
L->Next = t;
return;
}
List Temp = L;
if(flag == 0)//按剩余服务时间排序
{
if(WaitList->Next->status == 'R')//非抢占式,忽略链表的第一个作业
Temp = Temp->Next;
if(Temp->Next == NULL)
{
L->Next->Next = t;
return;
}
while(t->remaining_time >= Temp->Next->remaining_time)//剩余处理时间多的靠后站
{
Temp = Temp->Next;
if(Temp->Next == NULL)//判断链表结尾
{
Temp->Next = t;
return;
}
}
t->Next = Temp->Next;
Temp->Next = t;
return;
}
else if(flag == 1)//按到达时间排序
{
if(Temp->Next == NULL)
{
L->Next = t;
return;
}
while(t->arrival_time >= Temp->Next->arrival_time)//来的晚的靠后站
{
Temp = Temp->Next;
if(Temp->Next == NULL)//判断链表结尾
{
Temp->Next = t;
return;
}
}
t->Next = Temp->Next;
Temp->Next = t;
return;
}
}
void Delete(List L, jobInfo *t)
{
L->Next = t->Next;
t->Next = NULL;
}
void solve()
{
CurrentTime = 0;
record = (char*)realloc(record, sizeof(char)*CurrentTime);
while(CreateList->Next != NULL || WaitList->Next != NULL)//创建队列和就绪队列都不为空,就继续处理
{
while(CreateList->Next != NULL && CreateList->Next->arrival_time == CurrentTime)//将创建队列的作业放入就绪队列
{
jobInfo *create_first = CreateList->Next;
Delete(CreateList, create_first);
Insert(WaitList, create_first, 0);
}
if(WaitList->Next != NULL)//就绪队列有作业
{
jobInfo *wait_first = WaitList->Next;
wait_first->status = 'R';
Show_Ing();
record[CurrentTime++] = wait_first->name;//标记
wait_first->remaining_time--;//剩余时间--
if(wait_first->remaining_time == 0)//服务时间用完
{
wait_first->finish_time = CurrentTime;
Delete(WaitList, wait_first);
Insert(FinishList, wait_first, 1);
wait_first->status = 'F';
}
continue;
}
Show_Ing();
record[CurrentTime++] = '*';
}
Show_Ing();
}
void Show_Before()
{
List Temp = CreateList->Next;
printf("作业信息\n");
printf("%s\t%s\t%s\n", "Name", "Arrival", "Service");
while(Temp != NULL)
{
printf("%c\t%d\t%d\n", Temp->name, Temp->arrival_time, Temp->service_time);
Temp = Temp->Next;
}
putchar('\n');
}
void Show_Ing()
{
printf("%s\t%s\t%s\t%s=%d\n", "Name", "Remain", "Status", "Time", CurrentTime);
List Temp = WaitList->Next;
while(Temp != NULL)
{
printf("%c\t%d\t%c\n", Temp->name, Temp->remaining_time, Temp->status);
Temp = Temp->Next;
}
/*Temp = CreateList->Next;
while(Temp != NULL)
{
printf("%c\t%d\t%c\n", Temp->name, Temp->remaining_time, Temp->status);
Temp = Temp->Next;
}*/
Temp = FinishList->Next;
while(Temp != NULL)
{
printf("%c\t%d\t%c\n", Temp->name, Temp->remaining_time, Temp->status);
Temp = Temp->Next;
}
putchar('\n');
}
void Show_After()
{
List Temp = FinishList->Next;
printf("结果详情\n");
printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "Name", "Arrival", "Start", "Finish", "Service", "cycling", "W=T/Ts");
while(Temp != NULL)
{
int zz = Temp->finish_time-Temp->arrival_time;
printf("%c\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", Temp->name, Temp->arrival_time, Temp->finish_time-Temp->service_time, Temp->finish_time, Temp->service_time, zz, 1.0*zz/Temp->service_time);
Temp = Temp->Next;
}
putchar('\n');
printf("SJF调度时间图\n\t|");
for(int i=0; i<=CurrentTime; i++)
printf("%-4d", i);
printf("\n");
Temp = FinishList->Next;
while(Temp!=NULL)
{
printf("%c\t|", Temp->name);
for(int i=0; i<=CurrentTime; i++)
{
if(record[i] == Temp->name)
printf("——");
else
printf(" ");
}
printf("\n");
Temp = Temp->Next;
}
printf("\n");
}
/*
a 0 5
b 1 3
c 2 1
d 3 1
e 4 2
wym 0 5
bby 11 4
hss 1 1
szy 2 1
pyl 5 2
sjl 0 1
*/