【操作系统】学习笔记(三)基于时间片轮转的进程调度算法

本文主要用来分享基于时间片轮转的进程调度算法,但是在分享之前,我还是先来整理一下关于进程调度的基本理论。 
调度是决定或者安排事物发展次序的策略。进程的调度就是决定哪个进程来使用处理机。
操作系统的3级调度:
1.作业调度,又叫高级调度。决定将外存上的哪些作业调到内存的就绪队列,等待执行。
2.进程调度,又叫低级调度,决定就绪队列中的哪个进程将获得处理机。
3.交换调度,又叫中级调度,为了提高内存的利用率和系统的吞吐量(单位时间内完成工作量 总和 ),也就是将内存中的作业调到外存去 等待。
调度的类型:
     1.仅有进程调度的调度队列模型,运用在分时系统中。
     2.具有高级和低级调度的调度队列模型。
     3.具有3级调度的调度队列模型(批处理系统中)。
进程调度的方式:
     1.非剥夺式:一旦占有处理机,直至完成或者阻塞。
     2.剥夺式:就是可以剥夺别的进程占有的处理机。
       剥夺有以下原则:
          a.短作业优先
          b.时间片轮转
          c.优先权原则
什么样的情况才会引起进程调度??
     ·正在执行的进程执行完毕。
     ·执行中的进程遇到输入输出。
     ·时间片完成
     ·在进程通信或者同步的过程中执行了某些操作,如p操作(让权等待)。
     ·高优先者进入(在实时系统)
时间片轮转的进程调度算法,就是每个进程执行给定的时间片,时间片执行完之后,就将处理机让给其他的进程去使用。下边给出
基于时间片轮转的进程调度算法的实现代码:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<queue>

int roundTime = 1;//定义时间片为1
//进程信息节点
typedef struct NodeInfo
{
	char m_name;//进程名称
	int m_arriveTime;//进程的到达时间
	int m_totalTime;//进程执行完成需要的总时间
	int m_doneTime;//进程已经执行的时间
	int m_restTime;//进程还需要的执行的时间
	friend istream& operator>>(istream& is,NodeInfo& x)//进程信息的输入
	{
		is>>x.m_name>>x.m_arriveTime>>x.m_totalTime>>x.m_doneTime>>x.m_restTime;
		return is;
	}
	friend ostream& operator<<(ostream& os,NodeInfo& x)//进程信息的输出
	{
		cout<<x.m_name<<"	   " <<x.m_arriveTime<<"	     "<<x.m_totalTime<<"      "<<
				x.m_doneTime<<"	   "<<x.m_restTime<<endl;
		return os;
	}
} NodeInfo;
class Scheduling
{
public:
	Scheduling()
	{}
	//新的进程进入就绪队列
	void PushNewProcess(const NodeInfo& x)
	{
		_ready.push(x);
	}
	//按照时间片轮转进行执行
	void ServerProcess()
	{
		if(_ready.empty())
			return;
		NodeInfo top = _ready.front();//找到队首进程
		while(!_ready.empty())
		{
			top = _ready.front();//找到队首进程
			top.m_restTime -= roundTime;
			top.m_doneTime += roundTime;
			if(top.m_restTime != 0)
			{
				_ready.pop();
				_ready.push(top);
			}
			else
			{
				_ready.pop();
				_finish.push(top);
			}
			Print();
		}
	}
	//打印出进程的相关信息
	void Print()
	{
		queue<NodeInfo> tmp;
		NodeInfo top;
		cout<<"name"<<" "<<"arriveTime"<<" "<<"totalTime"<<" "<<"doneTime"<<" "<<"restTime"<<endl;
		while(!_ready.empty())
		{
			top = _ready.front();
			cout<<top;
			tmp.push(top);
			_ready.pop();
		}
		//就绪队列中的进程信息,已经打印完成,将tmp里的信息转至就绪队列
		while(!tmp.empty())
		{
			top = tmp.front();
			_ready.push(top);
			tmp.pop();
		}

		while(!_finish.empty())
		{
			top = _finish.front();
			cout<<top;
			tmp.push(top);
			_finish.pop();
		}
		//完成队列中的进程信息,已经打印完成,将tmp里的信息转至完成队列
		while(!tmp.empty())
		{
			top = tmp.front();
			_finish.push(top);
			tmp.pop();
		}
	}
private:
	queue<NodeInfo> _ready;//就绪队列
	queue<NodeInfo> _finish;//完成进程的队列
};
void menu()
{
	cout<<"------基于时间片轮转的进程调度算法------"<<endl;
	cout<<"------0.退出系统------"<<endl;
	cout<<"------1.输入新的作业进入就绪队列--------"<<endl;
	cout<<"------2.服务作业------"<<endl;
	cout<<"请选择>:";
}
void Test()
{
	menu();
	//用作测试
	/*NodeInfo p[] = {{'A',0,4,0,4},
		{'B',1,2,1,1},
		{'C',2,5,0,5}};
	*/
	int choose = 0;
	Scheduling s;
	NodeInfo newPro;
	do
	{
		cin>>choose;
		switch(choose)
		{
			case 1:
			{
				cout<<"请输入进程的名称,到达时间,总共服务时间,已服务时间,还需服务时间"<<endl;
				cin>>newPro;
				s.PushNewProcess(newPro);
				break;
			}
			case 2:
			{
				s.ServerProcess();
				break;
			}
			case 0:
				return;
			default:
				break;
		}
		cout<<"请选择>:";
	}while(choose > 0);
}


程序运行结果如下:



  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(1)、假定系统有五个进程,每一个进程用一个进程控制块PCB来代表。进程控制块的格式 (2)、每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“要求运行时间”。 把五个进程按顺序排成循环队列,用指针指出队列连接情况。另用一标志单元记录轮到运行的进程。 (3)、处理器调度总是选择标志单元指示的进程运行。由于本实验是模拟处理器调度的功能,所以,对被选中的进程并不实际启动运行 (4)、进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一个轮到运行的进程。同时,应判断该进程的要求运行时间与已运行时间,若该进程要求运行时间≠已运行时间,则表示它尚未执行结束,应待到下一轮时再运行。若该进程的要求运行时间=已运行时间,则表示它已经执行结束,应把它的状态修改为“结束”(E)且退出队列。此时,应把该进程的进程控制块中的指针值送到前面一个进程的指针位置。 (5)、若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。 (6)、在所设计的称序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进称对列的变化。 (7)、为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值