#include<bits/stdc++.h>
#define W 1
#define R 2
#define F 3
#define PS 1
#define FCFS 2
#define SJF 3
#define MFQ 4
using namespace std;
const int maxn = 10+1;
const char State[maxn][maxn]={"0", "Wait", "Run", "Finish"};//进程状态
int choose;//用户选择
int TotPCB;//总进程个数
int NOWTIME;//模拟系统时间
typedef struct pcb
{
char name[maxn];
int priority, arriveTime, serveTime, AllCPUtime;
//分别为优先级,就绪时间,服务时间,已占用进程时间
int completeTime;
int state;
}*PCB, pb;
typedef struct Pr//进程
{
PCB Pcb;//该结点的代表的进程控制块
Pr *nex;//该节点的下一个结点
}*PCBQ;//进程控制块队列
PCBQ DataQ;//读入的数据
PCBQ ReadyQ;//就绪队列
PCBQ PCBBank;;//还在系统中进程队列
void outmenu();//菜单
//以下是算法
bool PSA();//优先级调度算法
bool FCFSA();//先来先服务调度算法
bool SJFA();//短作业优先调度算法
bool MFQA();//多级反馈队列调度算法
//以下是操作
void Init();//初始化
void InsertPCB(PCBQ, PCB);//将PCB插入指定队列
PCBQ FindPCB();//在当前NOWTIME条件下在DataQ中寻找有没有新的进程到达
void DisPlay(PCB);//显示该进程的信息
void View(PCBQ);//显示该队列的信息
bool IsEmpty(PCBQ);//检查队列是否为空
void OutTimeConsume();//输出平均周转时间和带权平均周转时间
PCBQ Pop(PCBQ);
int main()
{
freopen("data.in","r", stdin);
Init();
puts("请输入进程个数");
scanf("%d", &TotPCB);
puts("请分别输入这些进程的进程名、就绪时刻、服务时间、优先级");
for(int i=1; i<=TotPCB; ++i)
{
PCB p = (PCB)malloc(sizeof(pb));
scanf("%s %d %d %d", p->name, &p->arriveTime, &p->serveTime, &p->priority);
p->AllCPUtime = 0;
p->completeTime = -1;
p->state = W;//初始没有
InsertPCB(DataQ, p);
}
outmenu();
View(DataQ);
scanf("%d", &choose);
while (choose>4||choose<1)
{
puts("请输入正确的算法编号");
scanf("%d", &choose);
}
bool flag = false;
switch (choose)
{
case PS:
flag = PSA();
break;
case FCFS:
flag = FCFSA();
break;
case SJF:
flag = SJFA();
break;
case MFQ:
flag = MFQA();
break;
default:
puts("something wrong");
break;
}
if(flag) puts("调用成功");
else{
puts("错误退出");
}
return 0;
}
void outmenu()
{
puts("本调度系统均采用非抢占调度,以下是可供调度算法,请选择");
puts("1.最高优先数优先算法\n2.先来先服务算法\n3.短作业优先算法\n4.多级反馈\n");
}
bool PSA()
{
puts("现在在调用最高优先数优先算法\n");
while (!IsEmpty(DataQ)||!IsEmpty(ReadyQ))//当没有进程再来的时候并且就绪队列进程都运行完就结束循环
{
//寻找当前系统时间有没有新进程到达
PCBQ NewPCB;
while((NewPCB = FindPCB()) != NULL)
{
PCBQ node = (PCBQ)malloc(sizeof(Pr));
node->Pcb = NewPCB->Pcb;
node->nex = NULL;
//按照当前的算法将新进程插入就绪队列
PCBQ head = ReadyQ;
while(head->nex&&node->Pcb->priority<=head->nex->Pcb->priority) head = head->nex;
node->nex = head->nex;
head->nex = node;
}
if(IsEmpty(ReadyQ)) ++NOWTIME;//模拟系统时间片
else{
//就绪队列不为空要进行调度
PCBQ node = Pop(ReadyQ);
node->Pcb->state = R;
printf("进程%s信息入下\n", node->Pcb->name);
DisPlay(node->Pcb);
puts("");
puts("就绪队列信息如下");
View(ReadyQ);
puts("");
puts("各个进程的PCB如下");
View(PCBBank);
puts("");
node->Pcb->state = F;
node->Pcb->AllCPUtime += node->Pcb->serveTime;
node->Pcb->completeTime = NOWTIME+node->Pcb->serveTime;
NOWTIME += node->Pcb->serveTime;
}
}
puts("结束以下是结果");
View(PCBBank);
OutTimeConsume();
return true;
}
bool FCFSA()
{
puts("现在在调用先来先服务算法");
while (!IsEmpty(DataQ)||!IsEmpty(ReadyQ))//当没有进程再来的时候并且就绪队列进程都运行完就结束循环
{
//寻找当前系统时间有没有新进程到达
PCBQ NewPCB;
while((NewPCB = FindPCB()) != NULL)
{
PCBQ node = (PCBQ)malloc(sizeof(Pr));
node->Pcb = NewPCB->Pcb;
node->nex = NULL;
//按照当前的算法将新进程插入就绪队列
PCBQ head = ReadyQ;
while (head->nex) head = head->nex;
head->nex = node;
}
if(IsEmpty(ReadyQ)) ++NOWTIME;//模拟系统时间片
else{
//就绪队列不为空要进行调度
PCBQ node = Pop(ReadyQ);
node->Pcb->state = R;
printf("进程%s信息入下\n", node->Pcb->name);
DisPlay(node->Pcb);
puts("");
puts("就绪队列信息如下");
View(ReadyQ);
puts("");
puts("各个进程的PCB如下");
View(PCBBank);
puts("");
node->Pcb->state = F;
node->Pcb->AllCPUtime += node->Pcb->serveTime;
node->Pcb->completeTime = NOWTIME+node->Pcb->serveTime;
NOWTIME += node->Pcb->serveTime;
}
}
puts("结束以下是结果");
View(PCBBank);
OutTimeConsume();
return true;
}
bool SJFA()
{
puts("现在在调用短作业优先算法");
while (!IsEmpty(DataQ)||!IsEmpty(ReadyQ))//当没有进程再来的时候并且就绪队列进程都运行完就结束循环
{
//寻找当前系统时间有没有新进程到达
PCBQ NewPCB;
while((NewPCB = FindPCB()) != NULL)
{
PCBQ node = (PCBQ)malloc(sizeof(Pr));
node->Pcb = NewPCB->Pcb;
node->nex = NULL;
//按照当前的算法将新进程插入就绪队列
PCBQ head = ReadyQ;
while(head->nex&&node->Pcb->serveTime>=head->nex->Pcb->serveTime) head = head->nex;
node->nex = head->nex;
head->nex = node;
}
if(IsEmpty(ReadyQ)) ++NOWTIME;//模拟系统时间片
else{
//就绪队列不为空要进行调度
PCBQ node = Pop(ReadyQ);
node->Pcb->state = R;
printf("进程%s信息入下\n", node->Pcb->name);
DisPlay(node->Pcb);
puts("");
puts("就绪队列信息如下");
View(ReadyQ);
puts("");
puts("各个进程的PCB如下");
View(PCBBank);
puts("");
node->Pcb->state = F;
node->Pcb->AllCPUtime += node->Pcb->serveTime;
node->Pcb->completeTime = NOWTIME+node->Pcb->serveTime;
NOWTIME += node->Pcb->serveTime;
}
}
puts("结束以下是结果");
View(PCBBank);
OutTimeConsume();
return true;
}
bool MFQA()
{
puts("现在在调用多级反馈队列算法");
//因为使用多级反馈,所以还要再增加两个,而ReadQ已经初始化完成那么
//新的就绪队列和ReadQ一样就可以
PCBQ ReadyQ2 = (PCBQ)malloc(sizeof(Pr));
PCBQ ReadyQ3 = (PCBQ)malloc(sizeof(Pr));
ReadyQ2->Pcb = ReadyQ3->Pcb = ReadyQ->Pcb = NULL;
ReadyQ3->nex = ReadyQ2->nex = ReadyQ->nex = NULL;
while (!IsEmpty(DataQ)||!IsEmpty(ReadyQ)||!IsEmpty(ReadyQ2)||!IsEmpty(ReadyQ3))//当没有进程再来的时候并且就绪队列进程都运行完就结束循环
{
//寻找当前系统时间有没有新进程到达
PCBQ NewPCB;
while((NewPCB = FindPCB()) != NULL)
{
PCBQ node = (PCBQ)malloc(sizeof(Pr));
node->Pcb = NewPCB->Pcb;
node->nex = NULL;
//按照当前的算法将新进程插入就绪队列
PCBQ head = ReadyQ;
while(head->nex&&node->Pcb->priority<=head->nex->Pcb->priority) head = head->nex;
node->nex = head->nex;
head->nex = node;
}
//队列时间片设置123
if(IsEmpty(ReadyQ)&&IsEmpty(ReadyQ2)&&IsEmpty(ReadyQ3)) ++NOWTIME;//模拟系统时间片
else{
//就绪队列不为空要进行调度
PCBQ node = NULL;
int time = 0;
if(!IsEmpty(ReadyQ)){
time = 1;
node = Pop(ReadyQ);
}
else if(!IsEmpty(ReadyQ2)){
time = 2;
node = Pop(ReadyQ2);
}
else if(!IsEmpty(ReadyQ3)){
time = 3;
node = Pop(ReadyQ3);
}
node->Pcb->state = R;
printf("进程%s信息入下\n", node->Pcb->name);
DisPlay(node->Pcb);
puts("");
puts("就绪队列1信息如下");
View(ReadyQ);
puts("");
puts("就绪队列2信息如下");
View(ReadyQ2);
puts("");
puts("就绪队列3信息如下");
View(ReadyQ3);
puts("");
puts("各个进程的PCB如下");
View(PCBBank);
puts("");
cout<<"time1 = "<<time<<endl;
int rest = node->Pcb->serveTime-node->Pcb->AllCPUtime;
if(rest>=time) node->Pcb->AllCPUtime += time, NOWTIME += time;
else node->Pcb->AllCPUtime += rest, NOWTIME += rest;
if(node->Pcb->AllCPUtime==node->Pcb->serveTime){
node->Pcb->completeTime = NOWTIME;
node->Pcb->state = F;
}
if(node->Pcb->state==F) continue;
node->Pcb->state = W;
// cout<<"time1 = "<<time<<endl;
switch (time)
{
case 1:
InsertPCB(ReadyQ2, node->Pcb);
break;
case 2:
InsertPCB(ReadyQ3, node->Pcb);
break;
case 3:
InsertPCB(ReadyQ3, node->Pcb);
break;
default:
puts("something wrong in MFQA");
puts("请联系作者来解决");
return false;
break;
}
}
}
View(PCBBank);
OutTimeConsume();
return true;
}
void Init(){
//方便操作建立表头结点
PCBBank = (PCBQ)malloc(sizeof(Pr));
PCBBank->nex = NULL;
PCBBank->Pcb = NULL;
ReadyQ = (PCBQ)malloc(sizeof(Pr));
ReadyQ->nex = NULL;
ReadyQ->Pcb = NULL;
DataQ = (PCBQ)malloc(sizeof(Pr));
DataQ->nex = NULL;
DataQ->Pcb = NULL;
NOWTIME = 0;
}
void InsertPCB(PCBQ q, PCB node)
{
PCBQ head = q;
while (head->nex) head = head->nex;
PCBQ t = (PCBQ)malloc(sizeof(Pr));
t->Pcb = node;
t->nex = NULL;
head->nex = t;
}
PCBQ FindPCB()
{
PCBQ head = DataQ;
PCBQ ret = NULL;
if(head->nex && head->nex->Pcb->arriveTime<=NOWTIME)
{
ret = (PCBQ)malloc(sizeof(Pr));
ret->Pcb = head->nex->Pcb;
ret->nex = NULL;
InsertPCB(PCBBank, ret->Pcb);
PCBQ t = head->nex;
head->nex = t->nex;
free(t);
}
return ret;
}
void DisPlay(PCB node){
printf("进程名:%s 优先级:%d 到达时间:%d 需要服务时间:%d 完成时间:%d 状态:%s\n",
node->name, node->priority,
node->arriveTime, node->serveTime,
node->completeTime, State[node->state]);
}
void View(PCBQ head){
PCBQ node = head;
if(node->nex == NULL){
puts("该就绪队列暂时为空");
return;
}
puts("进程名 优先级 到达时间 需要服务时间 完成时间 状态 ");
while (node->nex)
{
printf("%-7s %-7d %-9d %-13d %-9d %-8s\n",
node->nex->Pcb->name, node->nex->Pcb->priority,
node->nex->Pcb->arriveTime, node->nex->Pcb->serveTime,
node->nex->Pcb->completeTime, State[node->nex->Pcb->state]);
node = node->nex;
}
}
bool IsEmpty(PCBQ head){
return head->nex==NULL;
}
void OutTimeConsume()
{
double t = 0, w = 0;
PCBQ q = PCBBank;
while (q->nex)
{
t += q->nex->Pcb->completeTime-q->nex->Pcb->arriveTime;
w += (q->nex->Pcb->completeTime-q->nex->Pcb->arriveTime)*1.0/(1.0*q->nex->Pcb->serveTime);
q = q->nex;
}
t /= (1.0*TotPCB);
w /= (1.0*TotPCB);
printf("平均周转时间为:%f 带权平均周转时间为:%f\n", t, w);
}
PCBQ Pop(PCBQ head)
{
PCBQ ret = (PCBQ)malloc(sizeof(Pr));
PCBQ p = head->nex;
if(p){
head->nex = p->nex;
ret->Pcb = p->Pcb;
ret->nex = NULL;
free(p);
}
return ret;
}
实验2 进程调度
于 2022-06-14 16:47:01 首次发布
本文档介绍了如何实现四种调度算法(PSA、FCFS、SJF和MFQ),包括优先级调度、先来先服务、短作业优先及多级反馈队列,通过C++代码展示了从数据输入到算法运行的全过程,包括进程创建、菜单选择、调度执行和性能统计。
摘要由CSDN通过智能技术生成