先来先服务调度算法&短时间调度算法&高优先权调度算法

目录

一 ,先来先服务的调度算法

1.1 优缺点

二,最短作业优先算法SJF

2.1 SJF算法的优缺点:

2.2 SJF调度算法的问题:

三,高优先级调度算法

3.1 优先级调度的含义

3.2 调度算法的两种方式

3.3 优先级的类型

3.4 静态优先级

3.5 动态优先级


一 ,先来先服务的调度算法

最简单的调度算法,既可以用于作业调度 ,也可以用于程序调度,当作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”,直到该进程运行到完成或发生某事件堵塞后,进程调度程序才将处理机分配给其他进程。

1.1 优缺点

有利于长作业(进程)而不利于短作业(进程)

有利于CPU繁忙型作业(进程)而不利于I/O繁忙型作业(进程)

#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
	int countHomework;
	cout << "请输入作业数量:" << endl;
	cin >> countHomework;
	double **arr = new double *[countHomework];
	for (int i = 0;i < countHomework;i++)
	{
		arr[i] = new double[5];
	}
	for (int i = 0;i < countHomework;i++)//初始化
		for (int j = 0;j < 5;j++)
			arr[i][j] = 0;
	double starttime, endtime;
	cout << "请输入开始时间和运行时间" << endl;
	for (int i = 0;i < countHomework;i++) {
			cin >> starttime >> endtime;
			arr[i][1] = starttime;
			arr[i][2] = endtime;
	}
		double temp_1;
	double temp_2;
	for (int i = 0;i < countHomework;i++)
	{
		for (int j = i + 1;j < countHomework;j++)
		{
			if (arr[i][1] > arr[j][1])
			{
				temp_1 = arr[i][1];
				temp_2 = arr[i][2];
				arr[i][1] = arr[j][1];
				arr[i][2] = arr[j][2];
				arr[j][1] = temp_1;
				arr[j][2] = temp_2;
			}
		}
	}
	double currentTime;
	currentTime = arr[0][1];
	arr[0][3] = currentTime+arr[0][2];
	currentTime = arr[0][3];
	arr[0][4] = currentTime-arr[0][1];
	for (int i = 1;i < countHomework;i++)
	{
		arr[i][3] = currentTime + arr[i][2];
		currentTime += arr[i][2];
		arr[i][4] = currentTime - arr[i][1];//计算周转时间
	}
	cout << "进程号\t" << "开始时间\t" << "运行时间\t" << "周转时间\t" << endl;
	for (int i = 0;i < countHomework;i++) {
		arr[i][0] = i + 1;
		for (int j = 0;j < 5;j++)
		{
			cout << arr[i][j] << "\t";
		}
		cout << endl;
	}
}

二,最短作业优先算法SJF

SJF算法以进入系统的作业所要求的CPU时间为标准,是指对短作业或者短进程优先调度的算法,将每个进程与其估计运行时间进行关联选取估计计算时间最短的作业投入运行。

2.1 SJF算法的优缺点:

算法易于实现。但效率不高,主要弱点是忽视了作业等待时间;会出现饥饿现象。

SJF算法与FCFS算法的比较:

SJF的平均作业waiting time比FCFS要小,故它的调度性能比FCFS好。

2.2 SJF调度算法的问题:

实现SJF调度算法需要知道作业所需运行时间,否则调度就没有依据,要精确知道一个作业的运行时间是办不到的。

SJF是一种Non-preemptive(非抢占试)调度。

与SJF类似的一种preemptive 版本的调度叫shortest-remaining-time-first。

SJF是一种优先调度(priority scheduling),优先的是inverse of 预测的下一个中央处理器突发时间。

SJF调度算法是被证明了的最佳调度算法,这是因为对于给定的一组进程,SJF算法的平均周转时间最小。通过将短进程移到长进程之前,短进程等待时间的减少大于长进程等特时间的增加,因此,平均等特时间减少了。

#include"pch.h"
#include<iostream>
using namespace std;
int main()
{
	int jobNum = 0;
	cout << "请输入作业数量" << endl;
	cin >> jobNum;
	double **arr = new double*[jobNum];
	for (int i = 0;i < jobNum;i++)
	{
		arr[i] = new double[5];
	}
	for (int i = 0;i < jobNum;i++)
		for (int j = 0;j < 5;j++)
			arr[i][j] = 0;
	double startTime = 0, runningTime = 0;
	cout << "请输入开始时间和运行时间" << endl;
	for (int i = 0;i < jobNum;i++)
	{
		cin >> startTime >> runningTime;
		arr[i][1] = startTime;
		arr[i][2] = runningTime;
		arr[i][0] = 0;
	}
	double currentTime = arr[0][1];
	arr[0][3] = arr[0][1] + arr[0][2];
	currentTime = arr[0][3];
	
	arr[0][4] = currentTime - arr[0][1];
    cout << currentTime << endl;	arr[0][0] = 1;
	int count = 1;
	double priority = 0;//定义优先级
	while (count < jobNum)
	{
		int i_job = 0;
		double maxPriority = 0;
		for (int i = 1;i < jobNum ;i++) 
		{
			if ((arr[i][0] != 1) && (arr[i][1] < currentTime)) {
				priority = (currentTime - arr[i][1] + arr[i][2]) / (arr[i][2]);//求出优先级
				if (maxPriority < priority) {
					maxPriority = priority;
					i_job = i;
				}
			}
		}
		arr[i_job][3] = arr[i_job][2]+currentTime;
		currentTime += arr[i_job][2];
		arr[i_job][4] = currentTime - arr[i_job][1];/
		arr[i_job][0] = 1;
		count++;
	}
	cout << "作业号\t" << "开始时间\t" << "运行时间\t" << "结束时间\t" << "周转时间" << "\t" << endl;
	for (int i = 0;i < jobNum;i++)
	{
		arr[i][0] = i + 1;
		cout << arr[i][0] << "\t\t" << arr[i][1] << "\t\t" << arr[i][2] << "\t\t" << arr[i][3] << "\t\t" << arr[i][4] << "\t\t" << endl;

	}
}

三,高优先级调度算法

3.1 优先级调度的含义

(1)当该算法用于作业调度时,系统从后备作业队列中选择若干个优先级最高的,且系统能满足资源要求的作业装入内存运行。

(2)当该算法用于进程调度时,将把处理机分配给就绪进程队列中优先级最高的进程。

3.2 调度算法的两种方式

优先级调度算法细分成如下两种方式:

非抢占式优先级算法

在这种调度方式下,系统一旦把处理机分配给就绪队列中优先级最高的进程后,该进程就能一直执行下去,直至完成;或因等待某事件的发生使该进程不得不放弃处理机时,系统才能将处理机分配给另一个优先级高的就绪进程。

抢占式优先级调度算法

在这种调度方式下,进程调度程序把处理机分配给当时优先级最高的就绪进程,使之执行。一旦出现了另一个优先级更高的就绪进程时,进程调度程序就停止正在执行的进程,将处理机分配给新出现的优先级最高的就绪进程。

3.3 优先级的类型

进程的优先级可采用静态优先级和动态优先级两种,优先级可由用户自定或由系统确定。

3.4 静态优先级

(1)含义

静态优先级是在创建进程时确定进程的优先级,并且规定它在进程的整个运行期间保持不变。

(2)确定优先级的依据(确定优先级的依据通常有下面几个方面)

①进程的类型。通常系统进程优先级高于一般用户进程的优先级;交互型的用户进程的优先级高于批处理作业所对应的进程的优先级。

②进程对资源的需求。例如,进程的估计执行时间及内存需求量少的进程,应赋于较高的优先级,这有利缩小作业的平均周转时间。

③根据用户的要求。用户可以根据自己作业的紧迫程度来指定一个合适的优先级。

(3)优缺点

静态优先级法的优点是

①简单易行 ②系统开销小。

缺点是

①不太灵活,很可能出现低优先级的作业(进程),长期得不到调度而等待的情况。

②静态优先级法仅适用于实时要求不太高的系统。

3.5 动态优先级

(1)含义

动态优先级是在创建进程时赋予该进程一个初始优先级,然后其优先级随着进程的执行情况的变化而改变,以便获得更好的调度性能。

(2)优缺点

动态优先级优点是使相应的优先级调度算法比较灵活、科学,可防止有些进程一直得不到调度,也可防止有些进程长期垄断处理机。动态优先级缺点是需要花费相当多的执行程序时间,因而花费的系统开销比较大。

(此算法是根据进程运行时间以及等待时间来确定优先级)

#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
	cout << "请输入进程个数:" << endl;
	int processNumber;
	cin >> processNumber;
	double **array = new double*[processNumber];
	for (int i = 0;i < processNumber;i++)//申请空间
	{
		array[i] = new double[5];
	}
	for (int i = 0;i < processNumber;i++)//初始化
	{
		for (int j = 1;j < 5;j++)
			array[i][j] = 0;
		//array[i][0] = 0;
	}
	double startTime = 0.0, endTime = 0.0;
	cout << "请输入每个进程到达时间和执行时间:" << endl;
	for (int i = 0;i < processNumber;i++) { 
		cin >> startTime >> endTime;
		array[i][1] = startTime;
		array[i][2] = endTime;
	}
	double currentTime = array[0][1];	
       array[0][3] = currentTime + array[0][2];
	currentTime += array[0][2];
	array[0][4] = currentTime - array[0][1];
	array[0][0] = 1;
	double temp = 0;
	for (int i = 1;i < processNumber;i++)
	{
		for (int j = i + 1;j < processNumber;j++)
		{
			if (array[i][2] > array[j][2])
			{
				temp = array[i][2];
				array[i][2] = array[j][2];
				array[j][2] = temp;
				temp = array[i][1];
				array[i][1] = array[j][1];
				array[j][1] = temp;
			}
		}
	}
	int count = 1;
	while (count < processNumber) {
		for (int i = 1;i < processNumber;i++)
		{
			if (array[i][1] < currentTime&&array[i][0] != 1)
			{
				currentTime += array[i][2];
				array[i][3] = currentTime;//填入进程完成时间
				array[i][4] = currentTime - array[i][1];//周转时间
				count++;
				array[i][0] = 1;
			}
		}
	}
	for (int i = 0;i < processNumber;i++)
	{
		array[i][0] = i + 1;
	}
	cout << "进程号\t" << "开始时间\t" <<"运行时间\t"<<"周转时间\t"<< endl;
	for (int i = 0;i < processNumber;i++)
	{
		for (int j = 0;j < 5;j++)
			cout << array[i][j] << " \t";
		cout << endl;
	}

}

欢迎各位指出不足,以便以后更加完善,

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 实验目的 调度的实质是操作系统按照某种预定的策略来分配资源。进程调度的目的是分配CPU资源。由于进程调度程序执行的频率很,因此调度算法的好坏直接影响到操作系统的性能。本实验的目的是编程模拟实现几种常用的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。 2. 实验原理 [1]. 进程调度算法描述 进程调度算法包括先来先服务调度算法最短作业时间优抢占抢占)、最响应比调度算法4种。(每个人必须做FCFS,然后在后面的三种中任选一种,即每个人必须做2种调度算法的模拟。) [2]. 衡量算法性能的参数 计算进程的平均周转时间和平均带权周转时间。 3. 实验内容 (1)编程实现本实验的程序,要求: [1]. 建立进程的进程控制块,进程控制块至少包括: a) 进程名称; b) 进程需要执行时间; c) 进入就绪队列时间; d) 进程执行开始时间 e) 进程执行结束时间 [2]. 编程实现调度算法。 [3]. 进程及相关信息的输入。这些信息可以直接从键盘上输入,也可以从文件读取。 [4]. 时间片与时间流逝的模拟。本实验需要对算法的执行计时,程序应该提供计算时间的方法。一种最简单的方法是使用键盘,比如每敲一次空格代表一个时间片的流逝。另一种方法是使用系统时钟。 [5]. 一组进程序列执行完毕,打印出结果信息。程序需要计算出每个进程的开始执行时间、结束时间、周转时间和带权周转时间,并为整个进程序列计算平均周转时间和平均带权周转时间。程序将计算结果按一定的格显示在计算机屏幕上或输出到文件中。打印出进程调度顺序图。 [6]. 实现数据在磁盘文件上的存取功能。 (2)对下列就绪进程序列分别使用上面的几种算法进行调度,计算每种算法下的平均周转时间和平均带权周转时间。 进程号 到达时间 要求执行时间 0 0 1 1 1 35 2 2 10 3 3 5 4 6 9 5 7 21 6 9 35 7 11 23 8 12 42 9 13 1 10 14 7 11 20 5 12 23 3 13 24 22 14 25 31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值