进程调度有FCFS先来先服务,SPF短进程优先,RR轮转调度,优先级调度算法,高响应比优先算法,这里题目是使用前三种。
题目:
已知各进程的进入内存时间等如下:
进程名 到达时间 服务时间
A 0 5
B 1 3
C 2 2
D 3 1
先放代码:
#include<iostream>
#include<stdlib.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#define SUCCESS 1
#define FAIL 0
#define N 4//四个进程
using namespace std;
typedef struct PCBNode
{
char name;
int arrive;
int serve;
int start;
int finish;
int wait;
int T;//周转时间
float W;//带权周转时间
struct PCBNode*next;
}PCBNode,*PCBList;
int Creat(PCBList&L)
{
L=(PCBNode*)malloc(sizeof(PCBNode));
L->next=NULL;
printf("请输入每个进程的进程名 到达时间 服务时间\n");
PCBNode *s;
s=(PCBNode*)malloc(sizeof(PCBNode));
s=L;
while(s->next)
s=s->next;
for(int i=0;i<N;i++)
{
PCBNode*p;
p=(PCBNode*)malloc(sizeof(PCBNode));
cin>>p->name>>p->arrive>>p->serve;
p->next=NULL;
s->next=p;
s=p;
}
return SUCCESS;
}
int Sort(PCBList&L)//对进程执行顺序排序
{
PCBNode*p,*q;
p=(PCBNode*)malloc(sizeof(PCBNode));
q=(PCBNode*)malloc(sizeof(PCBNode));
for(p=L->next;p!=NULL;p=p->next)
{
for(q=p->next;q!=NULL;q=q->next)
{
if(p->arrive>q->arrive)
{
PCBNode*tmp;
tmp=new PCBNode;
tmp->name=p->name;tmp->arrive=p->arrive;tmp->serve=p->serve;
p->name=q->name;p->arrive=q->arrive;p->serve=q->serve;
q->name=tmp->name;q->arrive=tmp->arrive;q->serve=tmp->serve;
}
}
}
return SUCCESS;
}
int FCFS(PCBList&L)//FCFS算法
{
Sort(L);
PCBNode*p;
p=new PCBNode;
p=L->next;
p->start=p->arrive;
p->finish=p->start+p->serve;
p->wait=0;
p->T=p->finish-p->arrive;
p->W=float(p->T)/p->serve;
while(p->next)
{
if(p->next->arrive>p->finish)
p->next->start=p->arrive;
else
p->next->start=p->finish;
p->next->finish=p->next->start+p->next->serve;
p->next->wait=p->next->start-p->next->arrive;
p->next->T=p->next->finish-p->next->arrive;
p->next->W=float(p->next->T)/p->next->serve;
p=p->next;
}
return SUCCESS;
}
int SPF(PCBList&L)//SPF调度算法
{
Sort(L);
PCBNode*p;
p=new PCBNode;
p=L->next;
p->start=p->arrive;
p->finish=p->start+p->serve;
p->wait=0;
p->T=p->finish-p->arrive;
p->W=float(p->T)/p->serve;
while(p->next)
{
if(p->next->arrive>p->finish)
{
p->next->start=p->arrive;
}
else
{
PCBNode*s,*q;
s=new PCBNode;
q=new PCBNode;
for(s=p->next;s!=NULL;s=s->next)
{
for(q=s->next;q!=NULL;q=q->next)
{
if(s->serve>q->serve)
{
PCBNode*tmp;
tmp=new PCBNode;
tmp->name=s->name;tmp->arrive=s->arrive;tmp->serve=s->serve;
s->name=q->name;s->arrive=q->arrive;s->serve=q->serve;
q->name=tmp->name;q->arrive=tmp->arrive;q->serve=tmp->serve;
}
}
}
p->next->start=p->finish;
}
p->next->finish=p->next->start+p->next->serve;
p->next->wait=p->next->start-p->next->arrive;
p->next->T=p->next->finish-p->next->arrive;
p->next->W=float(p->next->T)/p->next->serve;
p=p->next;
}
}
int Print(PCBList&L)//进行输出
{
float sum=0;
PCBNode*p;
p=new PCBNode;
p=L->next;
cout<<"进程名 到达 服务 开始 完成 等待 周转 带权周转"<<endl;
while(p)
{
cout<<" "<<p->name<<" "<<p->arrive<<" "<<p->serve<<" "<<p->start<<" "<<p->finish<<" "<<p->wait<<" "<<p->T<<" "<<p->W<<endl;
sum+=p->W;
p=p->next;
}
cout<<"平均带权周转时间:"<<sum/N<<endl;
free(p);
return SUCCESS;
}
int RR(PCBList&L)//使用RR调度
{
int q,max_time,sjp;
cout<<"请输入时间配额:";
cin>>q;
vector<PCBNode> table[100];
deque<PCBNode> que;
Sort(L);
PCBNode *p;
p=new PCBNode;
p=L->next;
while(p)
{
table[p->arrive].push_back(*p);
max_time+=p->serve;
p=p->next;
}
max_time+=5;
PCBNode cur =*(L->next);
sjp = q;
for(int t = 0; t <= max_time; t++)
{
deque<PCBNode>::iterator it;
it = que.begin();
for(int i = 0; i < table[t].size(); i++)
que.push_front(table[t][i]);
if(que.empty()) continue;
if(!sjp || !cur.serve)
{
sjp = q;
que.erase(it);
if(cur.serve) que.push_back(cur);
else
{
L->next->finish=t;
}
if(!que.empty()) cur = que.front();
else continue;
}
cout << "t="<<t << "时,进程" << cur.name << "执行" << endl;
sjp--,cur.serve--;
}
}
int main()
{
system("color 07");
PCBList L;
Creat(L);
cout<<"使用FCFS调度算法结果:"<<endl;
FCFS(L);
Print(L);
cout<<"使用SPF调度算法结果:"<<'\n';
SPF(L);
Print(L);
cout<<"使用RR调度算法结果:"<<endl;
RR(L);
}
运行结果:
这里需要关注的几点:
1.在调试时,发现遇到点击下一步没有反应的情况,说明第一种处于cin行,需要输入后自动进入下一行,第二种处于cout,其中有endl、ends等无法继续,需要换成'\n'和' ';
2.关于头文件:
1>.头文件#include<algorithm>,可以实现直接调用里面的函数,例如循环,查找,计数,比较,搜索,复制等;
2>.头文件#include<vector>,vector是一个类模板, v.push_back(t) 是在数组的最后添加一个值为t的数据,v.empty()判断vector是否为空;
3>.头文件#include <queue>,是队列模板,主要队列queue类成员函数有:back()返回最后一个元素,empty()如果队列空则返回真,front()返回第一个元素,pop()删除第一个元,push()在末尾加入一个元素,size()返回队列中元素的个数;
4>.头文件#include <deque>,也是队列模板,不过和queue不同的是,deque支持两端插入删除,可以向数组一样随机访问,q.begin()/q.end()返回首迭代,q.push_front(x)/q.push_back()在队头/队尾插入元素,q.pop_front()/q.pop_back()弹出队头/队尾元素;
因为本人实力有限,代码比较复杂,有什么错的或者可以改进的还望指正!