操作系统实验(二)——作业调度算法

一个班(20信安)的同学搜到这篇别直接copy我的,代码仅供参考

一、FCFS

代码

#include<bits/stdc++.h>
using namespace std;
float ave_aroundtime; // 平均周转时间    
float ave_weight_aroundtime; // 平均带权周转时间    
int n;
float nowtime=0;
struct FCFS
{
	int name;
    char state;
	float arrivetime; // 到达时间(即进入外存的时间点)
	float servicetime; // 服务时间(所需cpu时间)
	float finishtime; // 结束时间
	float aroundtime; //周转时间(结束时间-到达时间,即进入外存到执行完毕所需时间)
    float weight_aroundtime; // 带权周转时间
};

bool cmp(FCFS a, FCFS b)
{
	return a.arrivetime<b.arrivetime;
}

void input(FCFS &p)
{
	cout << "请输入作业信息:" << endl;
	cout << "名称:";
	cin >> p.name;
	cout << "到达时间:";
	cin >> p.arrivetime;
	cout << "服务时间:";
	cin >> p.servicetime;
	cout << endl;
}

void out(FCFS a)
{
	cout << "作业" << a.name << "\t" << a.arrivetime << "\t\t" << a.servicetime << "\t\t" << a.aroundtime << endl;
}

void left_move(vector<FCFS> &a)
{
	for(int i=0; i<a.size(); i++){
		a[i] = a[i+1];
	}
	a.pop_back();// 弹出插入队尾的多出的队首元素	
}

void run(FCFS &node)
{
	node.finishtime = max(nowtime,node.arrivetime)+node.servicetime;
	node.aroundtime = node.finishtime - node.arrivetime;
	node.weight_aroundtime = node.aroundtime/node.servicetime;
	nowtime = node.finishtime;	
}

int main(){
	vector<FCFS> sort_queue;// 保存排序后的队列
    vector<FCFS> back_queue;// 后备队列
    vector<FCFS> wait_queue;// 就绪队列
	FCFS temp[10];
	cout << "输入作业数目:";
	cin >> n;
	for(int i=0; i<n; i++)
	{
		input(temp[i]);
		back_queue.push_back(temp[i]);// 进入后备队列
	}
	sort(back_queue.begin(), back_queue.end(), cmp);// 按到达时间从小到大排序
	sort_queue = back_queue;
	while(!back_queue.empty())
	{
		// 将一个作业从外存进入内存
		wait_queue.push_back(back_queue[0]);
		// 后备队列队首弹出
		left_move(back_queue);
		// 就绪队列作业开始占用cpu
		run(temp[wait_queue[0].name-1]);
		// 就绪队列作业完成,弹出
		wait_queue.clear();
	}
	cout << "FCFS算法进程的运行顺序为:" << endl;
	for(int i=0; i<n; i++)
	{
		cout << "作业" << sort_queue[i].name << "-->";
	}
	cout << "over";

	cout << "进程完成后具体信息记录:" << endl;
	cout << "进程\t到达时间\t服务时间\t周转时间\t" << endl; 
	for(int i=0; i<n; i++)
	{
		out(temp[i]);
		ave_aroundtime += temp[i].aroundtime;
		ave_weight_aroundtime += temp[i].weight_aroundtime;
	}
	ave_aroundtime/=n;
	ave_weight_aroundtime/=n;
	cout << "采用FCFS算法算得的平均周转时间为:" << ave_aroundtime << endl;
	cout << "采用FCFS算法算得的平均带权周转时间为:" << ave_weight_aroundtime << endl;
}

运行截图

在这里插入图片描述

二、SJF

代码

#include<bits/stdc++.h>
using namespace std;
float ave_aroundtime; // 平均周转时间    
float ave_weight_aroundtime; // 平均带权周转时间    
int n;
float nowtime=0;
struct SJF
{
	int name;
    char state;
	float arrivetime; // 到达时间(即进入外存的时间点)
	float servicetime; // 服务时间(所需cpu时间)
	float finishtime; // 结束时间
	float aroundtime; //周转时间(结束时间-到达时间,即进入外存到执行完毕所需时间)
    float weight_aroundtime; // 带权周转时间
};

bool cmp(SJF a, SJF b)
{
	return a.arrivetime<b.arrivetime;
}

void input(SJF &p)
{
	cout << "请输入作业信息:" << endl;
	cout << "名称:";
	cin >> p.name;
	cout << "到达时间:";
	cin >> p.arrivetime;
	cout << "服务时间:";
	cin >> p.servicetime;
	cout << endl;
}

void out(SJF a)
{
	cout << "作业" << a.name << "\t" << a.arrivetime << "\t\t" << a.servicetime << "\t\t" << a.aroundtime << endl;
}

void left_move(vector<SJF> &a)
{
	for(int i=0; i<a.size(); i++){
		a[i] = a[i+1];
	}
	a.pop_back();// 弹出插入队尾的多出的队首元素	
}

void run(SJF &node)
{
	node.finishtime = max(nowtime,node.arrivetime)+node.servicetime;
	node.aroundtime = node.finishtime - node.arrivetime;
	node.weight_aroundtime = node.aroundtime/node.servicetime;
	nowtime = node.finishtime;	
}

void i_first(vector<SJF> &back_queue, int first_i)
{
    // 前移该进程至队首
    SJF temp = back_queue[first_i];
    for(int i=first_i; i>0; i--)
    {
        back_queue[i] = back_queue[i-1];
    }
    back_queue[0] = temp;
}
void zero_flush(vector<SJF> &a)
{
    vector<SJF> b;
    for(int i=0; i<a.size(); i++)
    {
        if(a[i].name!=0) b.push_back(a[i]);
    }
    a.clear();
    for(int i=0; i<b.size(); i++)
    {
        a.push_back(b[i]);
    }
}
void fill(vector<SJF> &back_queue, vector<SJF> &sort_queue)
{
    if(sort_queue.empty()) return;
    for(int i=0; i<sort_queue.size(); i++)
    {
        if(sort_queue[i].arrivetime <= nowtime)
        {
            back_queue.push_back(sort_queue[i]);
            sort_queue[i].name=0;
        }
    }
    zero_flush(sort_queue);
    if(sort_queue.empty()) return;

    // 这里很关键,如果执行完进程后后备队列出现空窗期,则直接将nowtime赋值为下一个即将到来的进程的到来时间
    if(back_queue.empty())
    {
        nowtime = sort_queue[0].arrivetime;
        fill(back_queue, sort_queue);
    }
    return;
}



void short_first(vector<SJF> &back_queue)
{
    if(back_queue.empty()) return;
    int mini=0, minservicetime=back_queue[0].servicetime;
    // 遍历寻找在后备队列中的最短服务时间进程
    for(int i=0; i<back_queue.size(); i++)
    {
        if(minservicetime > back_queue[i].servicetime)
        {
            mini = i;
            minservicetime = back_queue[i].servicetime;
        }
    }
    // 前移该进程至队首
    SJF temp = back_queue[mini];
    for(int i=mini; i>0; i--)
    {
        back_queue[i] = back_queue[i-1];
    }
    back_queue[0] = temp;
}

void prt(vector<SJF> a)
{
    for(int i=0; i<a.size(); i++)
    {
        cout << a[i].name << " ";
    }
    cout << endl;
}
int main(){
	vector<SJF> sort_queue;// 保存排序后的队列
    vector<SJF> back_queue;// 后备队列
    vector<SJF> wait_queue;// 就绪队列
    vector<SJF> over_queue;// 执行完毕队列
	SJF temp[10];
	cout << "输入作业数目:";
    // input
	cin >> n;
	for(int i=0; i<n; i++)
	{
		input(temp[i]);
		sort_queue.push_back(temp[i]);// 进入后备队列
	}
	sort(sort_queue.begin(), sort_queue.end(), cmp);// 按到达时间从小到大排序

    // 第一次进程调度
        back_queue.push_back(sort_queue[0]);// 第一个进程直接进入
        left_move(sort_queue);
        // 一次进程调度
        wait_queue.push_back(back_queue[0]);
        left_move(back_queue);
        run(temp[wait_queue[0].name-1]);
        over_queue.push_back(wait_queue[0]);
        wait_queue.clear();

        cout << nowtime << "  "; 
        cout << "back:";
        prt(back_queue);
        cout << "sort:";
        prt(sort_queue);
	while(over_queue.size()!=n)
	{
        
        fill(back_queue, sort_queue); // 根据上一个进程结束时间nowtime填充后备队列back_queue
        short_first(back_queue); // 前移后备队列中服务时间最短的进程到队首
        // cout << back_queue[0].name << endl;
        cout << nowtime << "  "; 
        cout << "back:";
        prt(back_queue);
        cout << "sort:";
        prt(sort_queue);
        wait_queue.push_back(back_queue[0]); // 后备队列队首进程放到就绪队列中
		left_move(back_queue);// 后备队列队首弹出
		run(temp[wait_queue[0].name-1]);// 就绪队列作业开始占用cpu
        over_queue.push_back(wait_queue[0]);
		wait_queue.clear();// 就绪队列作业完成,弹出
	}
	cout << "SJF算法进程的运行顺序为:" << endl;
	for(int i=0; i<n; i++)
	{
		cout << "作业" << over_queue[i].name << "-->";
	}
    cout << "over" << endl;

	cout << "进程完成后具体信息记录:" << endl;
	cout << "进程\t到达时间\t服务时间\t周转时间\t" << endl; 
	for(int i=0; i<n; i++)
	{
		out(temp[i]);
		ave_aroundtime += temp[i].aroundtime;
		ave_weight_aroundtime += temp[i].weight_aroundtime;
	}
	ave_aroundtime/=n;
	ave_weight_aroundtime/=n;
	cout << "采用SJF算法算得的平均周转时间为:" << ave_aroundtime << endl;
	cout << "采用SJF算法算得的平均带权周转时间为:" << ave_weight_aroundtime << endl;
}

运行截图

在这里插入图片描述

三、小结

  1. 执行的进程数据是参考ppt最后给出的测试用例,为了简单期间ABCDE进程名称设置为12345.
    在这里插入图片描述

  2. 作业调度的过程没有用一个时钟进行不断推进,而是利用每一个执行进程直接计算结束时间,因此会出现进程执行完,后备队列依然为空的情况,这里就需要判断进程是否全部执行完毕,即一开始需要先输入进程的个数,否则无法判断后续是否还有未到来的进程。

  3. 短作业调度算法的过程中,需要在每次进程执行完毕,在后备队列内进程中搜索服务时间最短的进程进行执行,在这个过程中,需要找到合适的进程,将其挪到后备队列队首,出队放入就绪队列,然后占用CPU时间

  • 11
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

introversi0n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值