进程管理系统的设计与实现 SDUT 操作系统实训 项目 Java

进程管理系统的设计与实现

要求:
(1)设计一个完整的进程调度系统,至少包含三种常用的算法(FCFS、SPF、静态优先权、响应比、时间片轮转),系统中至少包含5个进程,并且能够体现进程的动态申请;

(2)定义PCB;

(3)结果要能够显示出进程的调度序列及进入系统的时间、运行时间、完成时间、周转时间、带权周转时间、优先权等必要信息;

(4〉设计的输入数据要能体现算法的思想

 

本人使用Java语言编写,编写过程中在网络中查找大量资料。

本人是本篇代码的唯一作者。

本代码仅限参考学习,禁止抄袭!
 

 

各算法介绍:

先来先服务算法First Come First Service(FCFS):

FCFS的意思是先来先服务(First Come First Service)。
顾名思义就是按照进程被添加到等待队列的先后顺序来进行调用的。


短进程优先算法Short Process First(SPF):

SPF的意思是短进程优先(Short Process First),服务时间短的进程在就绪队列前面。


静态优先级调度算法Static Priority-scheduling algorithm(SPSA):

系统在调度进程时按优先级从高到低进行调度,在进程运行过程中优先级不再动态地改变。


高响应比优先调度算法Highest Response Ratio Next(HRRN):

响应比 =(等待时间+要求服务时间)/ 要求服务时间
为每一个作业引入一个动态优先级,即优先级是可以改变的。
它随等待时间延长而增加,这将使长作业的优先级在等待期间不断地增加,
等到足够的时间后,必然有机会获得处理机。


时间片轮转算法Round Robin(RR):

系统把所有就绪进程按先来先服务规则排成一个队列,就绪队列中的所有进程,
可以依次轮流获得一个时间片的处理时间,然后系统又回到队列的开始部分,如此不断循环。

 

代码部分:

Main:

package osProject.sjs;

import java.io.*;
import java.util.*;

public class Main
{
	static int num;//进程数目
	static PCB[] arr = new PCB[100];
	static PCB[] arrUse = new PCB[100];
	static Scanner sc = new Scanner(System.in);
	
	public static void main(String[] args)
	{
		System.out.println("欢迎进入进程管理系统,请按照提示输入进程信息。");
		Main M = new Main();
		M.inputProcessInf(M);//输入进程,选择输入进程的方式
		M.displayProcessInf();//展示进程初始信息
		//进入菜单选择功能,可以使用多个算法调度进程
		while(true)
		{//此while为了多次选择功能i,在选择退出功能时置flag=1,然后退出
			//本程序使用arrUse而保留arr原数据,为了每次进入不同算法时不存在其他算法的遗留结果数据
			M.copyArray();//将arr中的数据内容拷贝到arrUse中,令算法使用arrUse中未被赋值过的干净数据
			int flag = 0;//用来标记是否需要退出选择算法,置1则退出算法
			M.displayMenu();//展示系统菜单,每执行完一次功能i,再次选择功能时展示一次
			while(true)
			{//为了防止输入i的错误导致无法选择功能,此while直到正确选择功能i时退出,每个if的最后都要有break
				try
				{//在try语句块中书写可能发生异常的代码(选择功能),增强程序健壮性
					int i = sc.nextInt();
					if(i == 1)
					{//选择先来先服务算法FCFS
						executeFCFS();//执行FCFS算法
						break;
					}
					else if(i == 2)
					{//选择短进程优先算法SPF
						executeSPF();//执行SPF算法
						break;
					}
					else if(i == 3)
					{//选择静态优先级调度算法SPSA
						executeSPSA();//执行SPSA算法
						break;
					}
					else if(i == 4)
					{//选择高响应比优先调度算法HRRN
						executeHRRN();//执行HRRN算法
						break;
					}
					else if(i == 5)
					{//时间片轮转算法RR
						executeRR();//执行RR算法
						break;
					}
					else if(i == 6)
					{//选择退出系统
						flag = 1;//flag置1,表示需要退出系统
						break;
					}
					else
					{//输入i不是要求的选项,提示重新选择
						System.out.println("输入有误,请重新输入:");//提示功能i选择的错误
						//输入错误时不需要break,需要重新输入
					}
				}
				catch(Exception e)
				{
					System.out.println("您输入的不是数字,请重新输入!");
					sc = new Scanner(System.in);//这一句要加,否则会进入死循环
				}
			}
			if(flag == 1)
			{//当flag置1时,退出系统
				break;
			}
		}
		sc.close();
	}
	
	private static void executeRR() 
	{//执行RR算法
		RR rr = new RR(num, arrUse, sc);//RR算法需要输入时间片大小,所以需要传入Scanner对象
		rr.run(); 
		System.out.println("请选择是否将本次算法执行结果存入文件?");
		System.out.println("1.是\t 2.否");
		while(true)
		{//while死循环是为了防止输入错误时令用户再次输入,否则输入错误后就跳出了,没法选择存文件
			int x = sc.nextInt();
			if(x == 1 || x == 2)  
			{
				if(x == 1)  rr.writeFile();//将类数组写入文件
				break;//当选择完文件操作后应该退出本层while
			}
			else
			{
				System.out.println("输入有误,请重新输入:");//提示文件操作的选择错误
				sc = new Scanner(System.in);
				//未选择完文件操纵,不需要退出本层while
			}
		}
	}

	private static void executeHRRN() 
	{//执行HRRN算法
		HRRN hrrn = new HRRN(num, arrUse);
		hrrn.run(); 
		System.out.println("请选择是否将本次算法执行结果存入文件?");
		System.out.println("1.是\t 2.否");
		while(true)
		{//while死循环是为了防止输入错误时令用户再次输入,否则输入错误后就跳出了,没法选择存文件
			int x = sc.nextInt();
			if(x == 1 || x == 2)  
			{
				if(x == 1)  hrrn.writeFile();//将类数组写入文件
				break;//当选择完文件操作后应该退出本层while
			}
			else
			{
				System.out.println("输入有误,请重新输入:");//提示文件操作的选择错误
				sc = new Scanner(System.in);
				//未选择完文件操纵,不需要退出本层while
			}
		}
	}

	private static void executeSPSA() 
	{//执行SPSA算法
		SPSA spsa = new SPSA(num, arrUse, sc);//SPSA算法要另外输入优先级,需要Scanner变量(也有其他方法)
		spsa.run(); 
		System.out.println("请选择是否将本次算法执行结果存入文件?");
		System.out.println("1.是\t 2.否");
		while(true)
		{//while死循环是为了防止输入错误时令用户再次输入,否则输入错误后就跳出了,没法选择存文件
			int x = sc.nextInt();
			if(x == 1 || x == 2)  
			{
				if(x == 1)  spsa.writeFile();//将类数组写入文件
				break;//当选择完文件操作后应该退出本层while
			}
			else
			{
				System.out.println("输入有误,请重新输入:");//提示文件操作的选择错误
				sc = new Scanner(System.in);
				//未选择完文件操纵,不需要退出本层while
			}
		}
	}

	private static void executeSPF() 
	{//执行SPF算法
		SPF spf = new SPF(num, arrUse);
		spf.run(); 
		System.out.println("请选择是否将本次算法执行结果存入文件?");
		System.out.println("1.是\t 2.否");
		while(true)
		{//while死循环是为了防止输入错误时令用户再次输入,否则输入错误后就跳出了,没法选择存文件
			int x = sc.nextInt();
			if(x == 1 || x == 2)  
			{
				if(x == 1)  spf.writeFile();//将类数组写入文件
				break;//当选择完文件操作后应该退出本层while
			}
			else
			{
				System.out.println("输入有误,请重新输入:");//提示文件操作的选择错误
				sc = new Scanner(System.in);
				//未选择完文件操纵,不需要退出本层while
			}
		}
	}

	private static void executeFCFS() 
	{//执行FCFS算法
		FCFS fcfs = new FCFS(num, arrUse);
		fcfs.run();
		System.out.println("请选择是否将本次算法执行结果存入文件?");
		System.out.println("1.是\t 2.否");
		while(true)
		{//此while为了防止输入错误时令用户再次输入,否则输入错误后就跳出了,
		//没法选择存文件,此while在选择文件操作完成后退出
			int x = sc.nextInt();
			if(x == 1 || x == 2)  
			{
				if(x == 1)  fcfs.writeFile();//将类数组写入文件
				break;//当选择完文件操作后应该退出本层while
			}
			else
			{
				System.out.println("输入有误,请重新输入:");
				sc = new Scanner(System.in);
				//未选择完文件操纵,不需要退出本层while
			}
		}
	}

	private void displayMenu()
	{
		System.out.println("功能菜单:");
		System.out.println("***********************************");
		System.out.println("*         1.先来先服务算法                *");
		System.out.println("*         2.短进程优先算法                *");
		System.out.println("*         3.静态优先级算法                *");
		System.out.println("*         4.高响应比优先调度算法      *");
		System.out.println("*         5.时间片轮转算法                *");
		System.out.println("*         6.退出系统                          *");
		System.out.println("***********************************");
		System.out.println("请选择要执行的操作:");
	}
	
	private void copyArray() 
	{//将arr中的数据内容拷贝到arrUse中,使用arrUse而保留arr中的原始数据
	//不能使用对象直接赋值,那样它们会引用同一块内容,两者会不独立
		for(int i = 0; i < num; i++)
		{
			arrUse[i] = new PCB();
			arrUse[i].setId(arr[i].getId());
			arrUse[i].setName(arr[i].getName());
			arrUse[i].setArriveTime(arr[i].getArriveTime());
			arrUse[i].setServiceTime(arr[i].getServiceTime());
			arrUse[i].setVisited(0);
		}
	}
	
	private void displayProcessInf()
	{//展示进程未执行算法时的初始信息
		System.out.println("进程初始信息如下:");
		for(int i = 0; i < num; i++)
		{
			//使用式样化输出函数printf()输出信息,使信息便于观看
			//左对齐加"-","8"指域宽为8,占8个字符字符串用"s",整型用"d",浮点类型用"f"
			System.out.printf("%-8s \t%-8s \t%-8s \t%-8s\n",
					"进程id", "进程名", "到达时间", "服务时间");
			System.out.printf("%-8d \t%-8s \t%-8d \t%-8d\n",
					arr[i].getId(), arr[i].getName(), arr[i].getArriveTime(), arr[i].getServiceTime());
		}
		System.out.println();
	}
	
	private void fileReadProcess()
	{//从文件中读入进程信息
		File file = new File("processInf.dat");
		try
		{
			FileInputStream fin = new FileInputStream(file);
			ObjectInputStream in = new ObjectInputStream(fin);
			num = fin.read();
			for(int i = 0; i < num; i++)
			{
				arr[i] = (PCB)in.readObject();
			}
			in.close();
			fin.close();
		}
		catch(Exception e)
		{
			System.out.println("文件\"processInf.dat\"不存在!请重新选择:");
			return;//若文件不存在需要直接return,否则会输出下方“已读入完成”的语句
		}
		System.out.println("文件\"processInf.dat\"中的算法数据已读入完成。");
		System.out.println();
	}
	
	private void fileWriteProcess()
	{//将进程块信息写入文件中
		File file = new File("processInf.dat");
		try
		{
			FileOutputStream fout = new FileOutputStream(file);
			ObjectOutputStream out = new ObjectOutputStream(fout);
			fout.write(num);
			for(int i = 0; i < num; i++)
			{
				out.writeObject(arr[i]);
			}
			out.close();
			fout.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		System.out.println("本次算法执行结果已存入文件\"processInf.dat\"中。");
		System.out.println();
	}

	private void readProcess()
	{//从控制台手动输入进程信息
		while(true)
		{
			try
			{//在try语句块中书写可能发生异常的代码,增强程序健壮性
				System.out.println("请输入进程数目(2-99):");
				num = sc.nextInt();
				if(num < 2 || num > 99)
				{
					System.out.println("您输入的数字不在要求范围内,请重新输入!");
				}
				else
				{
					System.out.println("进程数目为:" + num);
					System.out.println("请按照提示输入进程相关信息。");
					for(int i = 0; i < num; i++)
					{
						arr[i] = new PCB();
						arr[i].setId(i+1);
						System.out.println("第" + (i+1) + "个进程名:");
						arr[i].setName(sc.next());
						System.out.println("进程到达时间:");
						arr[i].setArriveTime(sc.nextInt());
						System.out.println("进程服务时间:");
						arr[i].setServiceTime(sc.nextInt());
						arr[i].setVisited(0);//置进程i未被执行过
					}
					break;//输入完毕,此处记得要break,否则会死循环
				}
			}
			catch(Exception e)
			{
				System.out.println("您输入的不是数字,请重新输入!");
				sc = new Scanner(System.in);//这一句要加,否则会进入死循环
			}
		}
		System.out.println("进程信息输入完成!");
	}
	
	private void inputProcessInf(Main M) 
	{//输入进程,选择输入进程的方式
		System.out.println("请选择输入进程方式:");
		System.out.println("1.手动输入\t 2.文件读入");
		while(true)
		{//为了防止输入x的错误导致无法选择功能,此while直到正确选择功能x时退出,每个if的最后都要有break
			int x = sc.nextInt();
			if(x == 1)
			{
				M.readProcess();//从控制台读入用户输入的进程块信息,读入一次进程信息,可以使用多个算法计算
				System.out.println("是否需要将进程信息保存到文件中?");
				System.out.println("1.是\t 2.否");
				while(true)
				{//此while为了防止输入错误时令用户再次输入
					int y = sc.nextInt();
					if(y == 1 || y == 2)  
					{
						if(y == 1)  M.fileWriteProcess();//将程序中的进程块信息写入文件中
						break;//当写入操作完成后,退出while循环
					}
					else
					{
						System.out.println("输入有误,请重新输入:");
						sc = new Scanner(System.in);
						//未正确选择操作,不需要退出本层while
					}
				}
				break;
			}
			else if(x == 2)
			{
				M.fileReadProcess();//从文件读入进程块信息
				break;
			}
			else
			{
				System.out.println("输入有误,请重新输入:");
				sc = new Scanner(System.in);
				//else中不用break,因为没有正确选择功能,需要在while中再次输入
			}
		}
	}

}

 

PCB(进程控制块):

package osProject.sjs;

import java.io.*;

public class PCB implements Serializable
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private int id;//进程id
	private String name;//进程名称
	private int arriveTime;//进程进入系统的时间(未开始服务),进程到达时间
	private int serviceTime;//进程服务时间,进程服务时间,需提前给出
	private int alreadyServiceTime;//已经服务的时间,进程执行时记录
	private int startTime;//进程服务开始时间
	private int endTime;//进程服务完成时间
	private int turnaroundTime;//周转时间,作业完成时间 - 作业到达时间
	private double turnaroundTimeWithRight;//带权周转时间,周转时间 /服务时间
	private int priority;//优先级
	private double responseRatio;//HRRN中的响应比
	private int visited;//是否被执行过,置0为未被执行过,置1为被执行过
	
	PCB(){}//构造函数
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getArriveTime() {
		return arriveTime;
	}

	public void setArriveTime(int arriveTime) {
		this.arriveTime = arriveTime;
	}

	public int getServiceTime() {
		return serviceTime;
	}
	
	public void setServiceTime(int serviceTime) {
		this.serviceTime = serviceTime;
	}
	
	public int getAlreadyServiceTime() {
		return alreadyServiceTime;
	}
	
	public void setAlreadyServiceTime(int alreadyServiceTime) {
		this.alreadyServiceTime = alreadyServiceTime;
	}

	public int getStartTime() {
		return startTime;
	}

	public void setStartTime(int startTime) {
		this.startTime = startTime;
	}

	public int getEndTime() {
  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值