一、进程调度
1.短作业优先调度算法
1.1设计内容
本设计模拟在单处理器情况下的进程调度,目的是加深对进程调度工作的理解,掌握不同调度算法的优缺点。设计程序模拟单处理机系统中的进程调度算法,在短作业优先调度算法、时间片轮转调度、最高优先级优先算法三种算法中选择两种实现。
1.2设计要求
每个进程由一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪W(Wait)、运行R(Run)或完成F(Finish)3中状态之一。
1.3设计思想
SJF算法是以作业的长短来计算优先级,作业越短,其他优先级越高。作业的长短是以作业所要求的运行时间来衡量的。SJF算法可以分别用于作业调度和进程调度。在把短作业优先调度算法用于作业调度时,它将从外存的作业后备队列中选择若干个估计运行时间最短的作业,优先将他们调入内存运行,直到所有进程完成调度为止。
1.4算法分析
1.4.1数据结构
struct PCB
{
char name[10]; //进程名
float arrivetime; //到达时间
float runtime; //运行时间
float starttime; //开始时间
float finishtime; //完成时间
float zztime; //周转时间
float dqzztime; //带权周转时间
};
1.4.2程序结构
1.5核心代码
void sjff(PCB *p,int N)
{
float arrivetime=0,runtime=0,starttime=0,finishtime=0,zztime=0,dqzztime=0;
//对进程信息初始化
sort(p,N);//调用sort函数
for(int m=0;m<N-1;m++)
{
/*先计算每个进程的完成时间*/
if(m==0)
p[m].finishtime=p[m].arrivetime+p[m].runtime;
else
{
if(p[m-1].finishtime >=p[m].arrivetime )
{
p[m].starttime=p[m-1].finishtime;}
else
{
p[m].starttime =p[m].arrivetime;}
p[m].finishtime=p[m].starttime+p[m].runtime;
}
int i=0;
/*根据for循环得出第m个进程完成时间内,其后有多少个进程到达*/
for(int n=m+1;n<=N-1;n++)
{
if(p[n].arrivetime<=p[m].finishtime)
i++;
}
/*通过对运行时间的比较,将运行时间最短的置为第m+1个进程*/
float min=p[m+1].runtime;
int next=m+1;//m+1=n
for(int k=m+1;k<m+i;k++)
{
if(p[k+1].runtime<min)
{
min=p[k+1].runtime;
next=k+1;
}
}
PCB temp;
temp=p[m+1];
p[m+1]=p[next];
p[next]=temp;
}
deal(p,N); //计算各个进程的开始时间,完成时间,周转时间,带权周转时间
output(p,N); //输出各个进程的详细信息
}
1.6测试数据或截图
2.时间片轮转调度算法
2.1设计内容
本设计模拟在单处理器情况下的进程调度,目的是加深对进程调度工作的理解,掌握不同调度算法的优缺点。设计程序模拟单处理机系统中的进程调度算法,在短作业优先调度算法、时间片轮转调度、最高优先级优先算法三种算法中选择两种实现。
2.2设计要求
每个进程由一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪W(Wait)、运行R(Run)或完成F(Finish)3中状态之一。
2.3设计思想
时间片轮转的主要思想是按顺序为每一个进程一次只分配一个时间片的时间。算 法要完成的功能是将各个进程按照时间片轮转运行的动态过程显示出来,其主要实现过 程是首先为每一个进程创建一个进程控制块,定义数据结构,说明进程包含的信息,实 现过程即用指针指向某一个进程,为其分配时间片,同时,该进程剩余时间减一,如此 循环执行。直到所有进程运行结束。
2.4算法分析
2.4.1数据结构
struct RR
{
char name[10];// 进程名称
int daodatime; // 到达时间
int fuwutime;// 服务时间
int shengyutime; // 剩余时间
char *state; // 所处状态
struct RR *next;
};
2.4.2程序结构
剩余时间=0?
Y N
N
所有进程是否完成
1.5核心代码
void run(RR *head)
{
struct RR *p, *t, *r;
int num;
vector<string> vec_out;
printf("请输入时间片:");
scanf("%d", &num);
while(head != NULL)
{
r = p = head;
while(p != NULL)
{
t = head;
p->shengyutime = p->shengyutime - num;
p->state = "运行";
string s = p->name;
vec_out.push_back(s);
if(p->shengyutime < 0)
p->shengyutime = 0;
printf("\n************程序开始运行*****************\n");
printf("进程 到达时间 服务时间 剩余时间 当前状态\n");
while(t != NULL)
{
printf("%2s%8d%8d%14d%10s\n", t->name, t->daodatime, t->fuwutime, t->shengyutime, t->state);
t = t->next;
}
if(p->shengyutime == 0)
{
if(p == head)
{
head = p->next;
free(p);
p = head;
}
else
{
r->next = p->next;
p = r->next;
r = p;
}
}
else
{
r = p;
p->state = "就绪";
p = p->next;
}
}
}
printf("执行顺序:\n");
printf("%s", vec_out[0].c_str());
for(int i = 1; i < vec_out.size(); i++)
{
printf("-->%s", vec_out[i].c_str());
}
}
1.6测试数据或截图
二、磁盘调度管理
1.设计内容
设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。
2.设计要求
(1)最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
(2)扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
(3)循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。
3.设计思想
该算法用vvector标准模板库模拟有许多扇区的磁盘,用srand()和rand()函数随机生成磁盘序列,存放到outfile文件流里面,设计一个选择函数,用switch选择需要调用的SSTF、SCAN、CSCAN算法,也用switch选择是否结束进程。
4.算法分析
4.1程序结构
5. 核心代码
(1)最短寻道时间算法
void SSTF(vector<int>m_vec,int position) //最短寻道时间算法
{
dis = 0;
average_distance = 0;
sort(m_vec.begin(),m_vec.end()); //从小到大排序,因为SSTF只能一个方向扫描
int i = 0;
for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++)
{
if(position >= *it)
i++;
}
int count = 0;
int left = i-1;
int right = i;
while(count<m_vec.size())
{
if((left >=0 && abs(m_vec[right]-position) > abs(m_vec[left]-position)) || right>=m_vec.size())
{
dis += abs(m_vec[left]-position);
Sleep(500);
cout<<"->"<<m_vec[left];
position = m_vec[left];
left--;
}
else{
dis += abs(m_vec[right]-position);
Sleep(500);
cout<<"->"<<m_vec[right];
position = m_vec[right];
right++;
}
count++;
}
compute_dis(m_vec,dis,average_distance);
}
(2)扫描算法
void SCAN(vector<int>m_vec,int position) //扫描算法
{
dis = 0;
average_distance = 0;
sort(m_vec.begin(),m_vec.end()); //从小到大排序
int i = 0;
for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){
if(position >= *it)
i++; //找到position所在的磁道
}
int left = i - 1; //先从外到内扫描
int right = i;
while(left >= 0)
{
dis += abs(position - m_vec[left]);
Sleep(500);
cout<<"->"<<m_vec[left];
position = m_vec[left];
left --;
}
while(right < m_vec.size())
{
dis += abs(position - m_vec[right]);
Sleep(500);
cout<<"->"<<m_vec[right];
position = m_vec[right];
right ++;
}
compute_dis(m_vec,dis,average_distance);
}
(3)循环扫描算法
void CSCAN(vector<int>m_vec,int position) //循环扫描算法
{
dis = 0;
average_distance = 0;
sort(m_vec.begin(),m_vec.end()); //从小到大排序
int i = 0;
for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++)
{
if(position >= *it)
i++; //找到position所在的磁道
}
int left = i - 1; //先从外到内扫描
int right = i;
while(left >= 0)
{
dis += abs(position - m_vec[left]);
Sleep(500);
cout<<"->"<<m_vec[left];
position = m_vec[left];
left --;
}
int len = m_vec.size()-1;
while(len >= right){
dis += abs(position - m_vec[len]);
Sleep(500);
cout<<"->"<<m_vec[len];
position = m_vec[len];
len --;
}
compute_dis(m_vec,dis,average_distance);
}
6.测试数据或截图