操作系统课程设计二、磁盘调度#
实验内容###
1、对于如下给定的一组磁盘访问进行调度:
请求服务到达 A B C D E F G H I J K L M N
访问的磁道号 30 50 100 180 20 90 150 70 80 10 160 120 40 110
2、要求分别采用先来先服务、最短寻道优先以及电梯调度算法进行调度。
3、要求给出每种算法中磁盘访问的顺序,计算出平均移动道数。
4、假定当前读写头在90号,电梯调度算法向磁道号增加的方向移动。
实验功能及设计思路###
程序功能:
-
支持从文件读入磁盘访问的访问磁道号和服务编号 。
-
支持查看在先来先服务、最短寻道优先以及电梯调度算法进行调度下的磁盘访问的顺序,计算出平均移动道数。
**设计思路: **
- 首先设计一个磁道访问请求数据结构体,保存访问的名称,请求的磁道号,和距离当前读写头的距离。
- 首先打开文件路径,读入数据,保存到结构体数组中,作为数据来源。
- 先来先服务(FCFS):由于读入数据是有序的,所以读入磁道请求之后,依次计算移动到这一磁道位置所需经过的路径长度,计算对平均道数的贡献。计算的次序即为该调度算法进行调度下的磁盘访问的顺序,依次输出显示即可。
- 最短寻到优先(SSTF)
该算法总数选择期要求访问的磁道与当前磁头距离最近的,依次实现每次的寻道时间最短。每次只需要比较剩余磁道距离当前磁头最短的一个磁道,移动到这个磁道位置即可。计算的次序即为该调度算法进行调度下的磁盘访问的顺序,依次输出显示即可。 - 电梯调度(SCAN)
该算法不仅考虑将要访问的磁道与当前磁道的距离,还要考虑磁头当前的移动方向。当磁头正在移动时候,SCAN算法选择下一个在其方向上面最近的磁道,直到这个方向不在存在请求的访问,转变方向,同样的操作,类似电梯的运行。每次调度时,只需要选择在当前方向最近的一个磁道访问,移动到这个磁道方向,除非这个方向不再存在磁道访问请求,此时转向。计算的次序即为该调度算法进行调度下的磁盘访问的顺序,依次输出显示即可。 - 在主程序中设计菜单,实现良好的操作界面以实现用户的功能调用。
源代码##
#include<bits/stdc++.h>
using namespace std;
struct track {
string name;
int id;
int dis;
};
vector<track>ve;
int cur = 90;
bool cmp_id(const track& t1, const track& t2) {
return t1.id < t2.id;
}
bool cmp_dis(const track& t1, const track& t2) {
return t1.dis>t2.dis;
}
void fcfs() {
vector<track>temp;
temp = ve;
int pos = cur;
double ave = 0;
cout << "名字 " << "磁道号 " << "移动道数
";
for (int i = 0; i < temp.size(); i++) {
temp[i].dis = abs(pos - temp[i].id);
ave += temp[i].dis;
pos = temp[i].id;
cout << setw(4) << temp[i].name << setw(8) << temp[i].id << setw(8) << temp[i].dis << endl;
}
ave /= temp.size();
cout << "fcfs平均移动道数:" << ave << endl << endl;
}
void sstf() {
vector<track>temp;
temp = ve;
int pos = cur;
double ave = 0;
cout << "名字 " << "磁道号 " << "移动道数
";
while (temp.size())
{
for (int i = 0; i < temp.size(); i++) {
temp[i].dis = abs(pos - temp[i].id);
}
sort(temp.begin(), temp.end(), cmp_dis);
int i = temp.size() - 1;
ave += temp[i].dis;
cout << setw(4) << temp[i].name << setw(8) << temp[i].id << setw(8) << temp[i].dis << endl;
pos = temp[i].id;
temp.pop_back();
}
ave /= ve.size();
cout << "fcfs平均移动道数:" << ave << endl << endl;
}
void scan() {
int pos = cur;
double ave = 0;
cout << "名字 " << "磁道号 " << "移动道数
";
list<track>l, g;//小于和大于cur的位置
for (int i = 0; i < ve.size(); i++) {
if (ve[i].id < pos)l.push_back(ve[i]);
else g.push_back(ve[i]);
}
l.sort(cmp_id);
g.sort(cmp_id);
l.reverse();
g.splice(g.end(), l);
for (list<track>::iterator it = g.begin(); it != g.end(); it++) {
it->dis = abs(pos - it->id);
pos = it->id;
ave += it->dis;
cout << setw(4) <<it->name << setw(8) << it->id << setw(8) << it->dis << endl;
}
ave /= ve.size();
cout << "fcfs平均移动道数:" << ave << endl << endl;
}
int main()
{
ifstream ifile;
ifile.open("/home/gzr/files/input/test2");
if (!ifile)
{
cout << "文件不存在." << endl;
return 0;
}
while (true)
{
track t;
ifile >> t.name >> t.id;
if (t.name == "")
{
break;
}
ve.push_back(t);
}
ifile.close();
int choice = 1;
while (choice != 0)
{
cout << "选择磁盘调度算法:" << endl;
cout << "1.先来先服务算法" << endl;
cout << "2.最短寻道优先" << endl;
cout << "3.电梯调度算法" << endl;
cout << endl;
cin >> choice; cout << endl;
switch (choice)
{
case 1:
fcfs();
break;
case 2:
sstf();
break;
case 3:
scan();
break;
case 0:
return 0;
default:
cout << "input error!" << endl;
break;
}
}
return 0;
}