OS第二次实验---进程调度算法的实现

一、实验目的

  在采用多道程序设计的系统中,往往有多个进程同时处于就绪状态。当就绪进程个数大于处理器个数时,就必须按照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,加深了解处理器调度的工作。

二、实验原理与内容

1. 实验原理

(1) 先来先服务
按照作业到达时间确定。进程的优先级按作业的到达时间以此排队,使得到达时间早的作业具有较高的优先级。
(2) 静态优先级算法
按照用户给出的优先级进行依次排队,使用户规定的优先级高的作业,具有较高的优先级。
(3) 静态时间片轮转法
将处理的进程按照时间顺序进行排队,规定一段执行时间该时间称为时间片。当该进程用完这一时间片时,系统将它送至就绪队列队尾,又把处理机分配给下一进程,再执行同样大小的时间片。这样,就绪队列中的所有进程,就可以依次轮流获得一个时间片的处理时间,然后系统又回到队列的开始部分。如此不断循环。

2.实验内容

  设计一个程序,根据不同的调度算法模拟操作系统对进程的调度。
  先来先到算法;静态优先级算法;静态时间片轮转算法

二、实验过程

  实验代码如下:

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cstring>
 
using namespace std;

struct text
{
	int num;				//进程数
	char text[100];				//进程名称
	double arr[100];				//到达时间
	double pri[100];				//优先级
	double revser[100];				//服务时间
	double str[100];				//开始时间
	double finsh[100];			//结束时间
	double turn[100];			//周转时间
	double weight_turn[100]	;			//带权周转时间
	double last[100];		//剩余时间 
	double ser_last[100]; 
}TEX;

void input()		//输入
{	
	int i;
	printf("输入进程数量\n");
	scanf("%d",&TEX.num);
	printf("输入进程名称,到达时间,服务时间,优先级\n");
	for(i = 0; i < TEX.num ; i++ )
	{
		cin>>TEX.text[i];
		cin>>TEX.arr[i];
		cin>>TEX.revser[i];		
		cin>>TEX.pri[i];
	}
	
}

void output(int i)
{
	cout<<"进程名称\t到达时间\t服务时间\t优先级\t开始时间\t结束时间\t周转时间\t带权周转时间\n";
	cout<<TEX.text[i]<<"\t\t"<<TEX.arr[i]<<"\t\t"<<TEX.revser[i]<<"\t\t"<<TEX.pri[i]<<"\t"<<TEX.str[i]<<"\t\t"<<TEX.finsh[i]<<"\t\t"<<TEX.turn[i]<<"\t\t"<<TEX.weight_turn[i]<<"\n";	
}

void output1(int i)
{
	cout<<"进程名称\t到达时间\t已服务时间\t剩余时间\n";
	cout<<TEX.text[i]<<"\t\t"<<TEX.arr[i]<<"\t\t"<<TEX.ser_last[i]<<"\t\t"<<TEX.last[i]<<"\n";	
}

void output2(int i)
{
	cout<<"正在运行的程序:  ";
	cout<<TEX.text[i]<<"\n";	
}

void FCFS()		//先来先到
{
	int i,j;
	double start;
	double end; 
	double point;
	input();
	start = 0;
	end = 0;
	for(i = 0 ; i < 100 ; i++)
	{
		for(j = 0 ; j < TEX.num ; j++)
		{
			if(TEX.arr[j] == i)
			{
				if(end <= TEX.arr[j])      //下个进程到达预计 
				{
					start = TEX.arr[j];
					end = start + TEX.revser[j];
				}
				else
				{
					start = end;
					end = TEX.revser[j] + start;
				}
				TEX.str[j] = start;
				TEX.finsh[j] = end;
				TEX.turn[j] = 	TEX.finsh[j] - TEX.arr[j];
				TEX.weight_turn[j] = TEX.turn[j]/TEX.revser[j];
				output(j);
			}
		}
	}
}												

void CIS()		//固定优先级
{
	int i,j;
	double start;
	double end; 
	double point;
	input();
	start = 0;
	end = 0;
	for(i = 0 ; i < 100 ; i++)
	{
		for(j = 0 ; j < TEX.num ; j++)
		{
			if(TEX.pri[j] == i)
			{
				if(end <= TEX.arr[j])		  //下个进程到达预计 
				{
					start = TEX.arr[j];
					end = start + TEX.revser[j];
				}
				else
				{
					start = end;
					end = TEX.revser[j] + start;
				}
				TEX.str[j] = start;
				TEX.finsh[j] = end;
				TEX.turn[j] = 	TEX.finsh[j] - TEX.arr[j];
				TEX.weight_turn[j] = TEX.turn[j]/TEX.revser[j];
				output(j);
			}
		}
	}
} 

void FCFSS()		//时间片
{
	int time=3;
	int i,j,k,m,n,o;
	double start;
	double end; 
	int point;
	double a_arr[100];
	input();
	start = 0;
	end = 0;
	k = 0;
	for(i = 0 ; i < 100 ; i++)		//进程排序 
	{
		for(j = 0 ; j < TEX.num ; j++)
		{
			if(TEX.arr[j] == i)
			{
				a_arr[k] = j;
				k++;
			}
		}
	}
	k=0;o=0;n=TEX.num;point=a_arr[0];start=TEX.arr[point];end=start;m=point;			//数据初始化 
	
	for(i=0;i<TEX.num;i++)
	{
		TEX.last[i]=TEX.revser[i];
	 }
	 
	  
	for(i = 0 ; i < 500 ; i++)
	{
		output2(m);
		if(i<TEX.num)		//接受进程 
		{
			TEX.str[m]=start;
			TEX.last[m]=TEX.revser[m];
		}
		
		if(TEX.last[m]<=3)			//进程判断 
		{
			TEX.finsh[m]=start+TEX.last[m];
			TEX.ser_last[m]=TEX.ser_last[m]+TEX.last[m];
			TEX.last[m]=0;
			for(j=0;j<n-o;j++)
			{
					a_arr[o+j]=a_arr[o+j+1]; 

			}
			output1(m);
			n--;
			o--;
		}
		
				start=start+3;		//时间加3 
				
		if(TEX.last[m]>3)
		{
			TEX.ser_last[m]=TEX.ser_last[m]+3;
			TEX.last[m]=TEX.last[m]-3;
			TEX.finsh[m]=TEX.str[m]+3;
		}
		
		for(k=0;k<n;k++)		//打印 
		{
			point=a_arr[k];
			output1(point);
		}
		cout<<n;
		cout<<"\n"<<"\n";
		o++;
		if(o==n)
		{
			o=0; 
		}
		m=a_arr[o];
		if(n==0)
		{
			break; 
		}
	}
	for(i=0;i<TEX.num;i++)		//打印 
	{
		output(i);
	}
	
}

int main()
{
	int a;
	cout<<"请选择服务:"<<endl<<"1.先来先服务算法"<<endl<<"2.静态优先级服务算法"<<endl<<"3.静态时间片轮转"<<endl<<"4.退出"<<endl;
	while(a<4)
	{
		cout<<"please input serve:";
		cin>>a;
		switch(a)
		{
		 	case(1):FCFS();break;
		 	case(2):CIS();break;
		 	case(3):FCFSS();break;
			default:break;		 		
		}
	} 

  *程序运行结果如下:
(1)先来先服务算法
在这里插入图片描述

(2)静态优先级算法
在这里插入图片描述

(3)时间片轮转法

在这里插入图片描述

四、实验总结

  本次实验了解了多道进程的处理过程,进一步感受了CPU的运行,有利于我们更好的了解操作系统。

五、实验体会及改进建议

  加强对算法及数据结构的了解,在实验过程中对于数据结构的不熟悉,导致我在实验过程中出现了很多问题。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实验目的】 1. 理解进程的概念,熟悉进程的组成; 2. 用高级语言编写和调试一个进程调度程序,以加深对进程调度算法的理解。 【实验准备】 1. 几种进程调度算法  短进程优先调度算法  高优先权优先调度算法  先来先服务调度算法  基于时间片的轮转调度算法 2. 进程的组成  进程控制块(PCB)  程序段  数据段 3. 进程的基本状态  就绪W(Wait)  执行R(Run)  阻塞B(Block) 【实验内容】 1. 例题 设计一个有 N个进程共行的进程调度程序。 进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。 4. 实验题目  编写并调试一个模拟进程调度程序,采用“最高优先数优先”调度算法对五个进程进行调度。“最高优先数优先”调度算法的基本思想是把CPU分配给就绪队列优先数最高的进程。静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定原则修改优先数。例如在进程获得一次CPU后就将其优先数减少1。或者,进程等待的时间超过某一时限时增加其优先数的值,等等。  编写并调试一个模拟进程调度程序,采用“轮转法”调度算法对五个进程进行调度。轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还为完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Next---YOLO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值