模拟一共用到了五个类,分别以代码段方式给出
环境:Visual Studio 2019
没什么水平,希望能帮到你
可在附件资源处直接下载,传送门:
附件资源C#操作系统抢占式最早截止时间算法模拟-其它文档类资源-CSDN下载
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Process_Scheduling_Simulation.Processes
{
public class ProcessPCB
{
public int priorityLevel; // 优先级
public Status state; // 进程状态
public enum Status
{
Ready = 0,
Runing = 1,
Block = 2,
}
public ProcessPCB()
{
priorityLevel = 0;
}
}
}
using Process_Scheduling_Simulation.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Process_Scheduling_Simulation.Processes
{
public class Process
{
public ProcessPCB processPCB;
public Process(ProcessPCB processPCB, int processID, int cycleTime, int cycleProcessingTime)
{
this.processID = processID;
this.processPCB = processPCB;
this.cycleTime = cycleTime;
this.cycleProcessingTime = cycleProcessingTime;
this.restTime = cycleProcessingTime;
this.deadLine = cycleTime;
this.queueEnterTime = 0;
}
public int processID; // 进程ID
public float cycleTime; // 进程周期时间
public float cycleProcessingTime;// 进程周期处理时间
public float deadLine; // 最迟截止时间
public float startTime; // 开始运行时间
public float restTime; // 还需运行时间
public float queueEnterTime; // 进入队列时间
}
}
using Process_Scheduling_Simulation.Common;
using Process_Scheduling_Simulation.Processes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Process_Scheduling_Simulation.Processes.ProcessPCB;
namespace Process_Scheduling_Simulation.Managers
{
public class ProcessManager : Singleton<ProcessManager>
{
public int[] resourceArray; // 系统资源数组
public int resourceTypes; // 系统资源种类
public List<Process> Processes = new List<Process>(); // 进程列表
public Queue<Process> readyQueue = new Queue<Process>(); // 就绪队列
Dictionary<int, Process> runingProcesses = new Dictionary<int, Process>(); // 正在运行的进程字典 [进程号,进程] 每个任务是循环的
public Bank bank; // 银行家算法所需变量
float nowTime; // 当前时间
public float Stoptime; // 模拟停止时间
public struct Bank
{
public int[,] Max; // [进程ID,资源数] 每个进程所需的总资源
public int[] Available; // 系统还可分配的资源数
public int[,] Allocation; // [进程ID,资源数] 每个进程已经分配的资源
public int[,] Need; // [进程ID,资源数] 每个进程总还需要的资源数
}
public ProcessManager()
{
}
int index = 0;
public void Init(int[] array)
{
resourceArray = array;
bank.Available = resourceArray;
nowTime = 0;
}
public Process CreatProcess(int cycleProcessingTime, int cycleTime)
{
Process process = new Process(
new ProcessPCB(),
++index,
cycleTime,
cycleProcessingTime
);
return process;
}
public void AddToRuningProcesses(Process process) // 添加到运行进程中
{
Console.WriteLine("processID:{0}加入运行进程", process.processID);
process.processPCB.state = Status.Ready;
runingProcesses.Add(process.processID, process);
Processes.Add(process);
}
Process temp;
// 最短剩余时间优先算法
public void StartSimulation()
{
SimulationInit();
RunProcess(temp);
}
List<Process> blockList = new List<Process>();
public void SimulationInit()
{
temp = Processes[0];
for (int i = 0; i < Processes.Count; i++) // 遍历进程列表中的每个元素
{
if(Processes[i].processPCB.state == Status.Block ) // 之前有进程被阻塞了
{
blockList.Add(Processes[i]);
temp = Processes[i];
}
}
if(blockList != null)
{
for(int i =0; i< blockList.Count; i++)
{
if(blockList[i].deadLine < temp.deadLine)
{
temp = blockList[i];
}
}
blockList.Clear();
return;
}
temp = Processes[0];
for (int i = 0; i < Processes.Count; i++) // 遍历进程列表中的每个元素
{
if (Processes[i].processPCB.state == Status.Ready) // 闲了一段时间又开始工作
{
if (Processes[i].deadLine < temp.deadLine)
{
temp = Processes[i]; // 让temp拿到deadLine最小的进程
}
}
}
}
public void RunProcess(Process process)
{
if(nowTime > Stoptime)
{
Console.WriteLine("finish");
return;
}
temp = process;
temp.processPCB.state = Status.Runing; // 让这个进程跑
for (int i = 0; i < Processes.Count; i++) // 遍历进程列表中的每个元素
{
if (Processes[i].processID != temp.processID && Processes[i].queueEnterTime == temp.queueEnterTime) // 对于列表中的其他同queueEnterTime进程
{
Processes[i].processPCB.state = Status.Block;
}
}
temp.startTime = temp.queueEnterTime < nowTime ? nowTime : temp.queueEnterTime;
Console.WriteLine("processID:{0}正在运行,此刻时间:{1}", temp.processID, nowTime);
if (IsBlocked()) // 如果被阻塞了
{
return;
}
else // 没被阻塞完成了
{
nowTime = nowTime + temp.restTime; // 更新当前时间
Console.WriteLine("processID:{0}在{1}时刻运行结束",temp.processID, nowTime);
temp.processPCB.state = Status.Ready;
temp.restTime = temp.cycleProcessingTime; // 重置剩余运行时间
temp.queueEnterTime = temp.queueEnterTime + temp.cycleTime; // 更新进入队列时间
temp.deadLine = temp.queueEnterTime + temp.cycleTime; // 更新死线
StartSimulation();
}
}
public bool IsBlocked()
{
// 当任意一个进程运行完时和另一个进程进入时判断,那么首先要知道这个进程运行完之前有没有进程进入
// 他如果被插队了就运行不完
for (int i = 0; i < Processes.Count; i++) // 遍历进程列表中的每个元素
{
if (Processes[i].processID != temp.processID) // 对于列表中的其他进程
{
if (Processes[i].queueEnterTime < temp.deadLine && Processes[i].deadLine < temp.deadLine) // 如果在正在运行的进程结束前进入了且死线更短
{
// 目前进程被阻塞先执行另一个进程
temp.processPCB.state = Status.Block;
nowTime = Processes[i].queueEnterTime > nowTime ? Processes[i].queueEnterTime : nowTime; // 更新当前时间
temp.restTime = temp.cycleProcessingTime - (nowTime - temp.startTime); // 设置当前进程剩余时间
Console.WriteLine("processID:{0}进程被processID:{1}进程阻塞,此刻时间:{2}", temp.processID, Processes[i].processID, nowTime);
// 开始另一个进程
RunProcess(Processes[i]);
return true;
}
if(Processes[i].queueEnterTime < temp.deadLine) // 在运行的进程结束前进入了,但是死线不比他短,那就被阻塞了
{
Processes[i].processPCB.state = Status.Block;
return false;
}
}
}
return false;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Process_Scheduling_Simulation.Common
{
public class Singleton<T> where T : new()
{
private static T instance;
public static T Instance
{
get
{
return Equals(instance, default(T)) ? (instance = new T()) : instance;
}
}
}
}
using Process_Scheduling_Simulation.Managers;
using Process_Scheduling_Simulation.Processes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Process_Scheduling_Simulation
{
class Program
{
static int[] array = new int[50];
string[] nums;
string t;
static void Main()
{
Program program = new Program();
Console.WriteLine("请输入有几个周期任务");
string input = Console.ReadLine();
Console.WriteLine("请分别逐行输入每个周期任务的周期处理时间和周期长度");
for(int i = 0; i < int.Parse(input); i++)
{
program.t = Console.ReadLine();
program.nums = program.t.Split(new string(" "), StringSplitOptions.None);
ProcessManager.Instance.AddToRuningProcesses(ProcessManager.Instance.CreatProcess(int.Parse(program.nums[0]), int.Parse(program.nums[1])));
}
Console.WriteLine("输入一个时间,在这个时间之后不会再开启新任务");
ProcessManager.Instance.Stoptime = int.Parse(Console.ReadLine());
//ProcessManager.Instance.AddToRuningProcesses(ProcessManager.Instance.CreatProcess(15, 40));
//ProcessManager.Instance.AddToRuningProcesses(ProcessManager.Instance.CreatProcess(10, 20));
//ProcessManager.Instance.AddToRuningProcesses(ProcessManager.Instance.CreatProcess(25, 50));
ProcessManager.Instance.StartSimulation();
}
}
}
使用方法见下图