前言
道程序设计中,经常是若干个进程同时处于就绪状态,为了使系统中的各进程有条不紊地运行,必须选择某种调度策略,以选择一个进程占用处理机。本次实验设计一个模拟单处理机调度的算法,以加深对处理机调度算法的理解。
要求
按照时间片轮转算法设计模拟调度程序。
输出进程的调度过程。
思路分析
由于本实验是按照处理机调度算法模拟实现处理机的调度,与真正的处理机调度过程并不完全相同,比如没有实现中断(时间片设为1),进程的运行也不是真正的运行,而是在屏幕上打印其运行时间等。所以要以文件的形式给出进程的信息,文件信息可参考如下:
进程ID 到达时间 估计运行时间 优先级 0 0 3 2 1 2 6 4 2 4 4 0 3 6 5 3 4 8 2 1
以下是实验的大致思路:
建立三个队列:PCB队列,就绪队列,完成队列。
PCB队列:保存将进入系统的进程。(由于没有实现中断,所以将进入系统运行的进程必须在程序运行前给出)。
就绪队列:到达进程进入系统的时间,将该进程放入就绪队列,等待调度。
完成队列:将“运行”完的进程放入完成队列。进程运行过程是在屏幕上打印相关信息。
使用轮转算法调度的进程应打印的信息包括:进程占用处理机序列,该进程每次占用处理机的开始时间与结束时间。统计出进程的周转时间T和带权周转时间W。
流程图
实现代码
ProcessControlBlock.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace OperatingSystemExperiment.Exp1 { enum ProcessStatus {
Ready,
Run,
Finish
} /// <summary>
/// 进程控制块 PCB
/// </summary>
class ProcessControlBlock { /// <summary>
/// 进程号
/// </summary>
public int ID; /// <summary>
/// 进程状态
/// </summary>
public ProcessStatus Status; /// <summary>
/// 进程到达时间
/// </summary>
public int ArriveTime; /// <summary>
/// 估计运行时间
/// </summary>
public int Time; /// <summary>
/// 已运行时间
/// </summary>
public int RunTime = 0; /// <summary>
/// 等待时间
/// </summary>
public int WaitTime; /// <summary>
/// 优先级
/// </summary>
public int Priority; /// <summary>
/// 链接指针
/// </summary>
public ProcessControlBlock Next; /// <summary>
/// 开始时间
/// </summary>
public int StartTime; /// <summary>
/// 结束时间
/// </summary>
public int FinishTime; public void Run() { this.Status = ProcessStatus.Run; if (RunTime >= Time) { this.Status = ProcessStatus.Finish; return;
} this.RunTime++;
} public void Wait() { this.WaitTime++;
} public override string ToString() => String.Format("{0} {1} {2}", ID, StartTime, FinishTime);
}
}CentralProcessUnit.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.IO;namespace OperatingSystemExperiment.Exp1 { class CentralProcessUnit { private List<ProcessControlBlock> PCBList = new List<ProcessControlBlock>(); private Queue<ProcessControlBlock> FinishQueue = new Queue<ProcessControlBlock>(); private Queue<ProcessControlBlock> ReadyQueue = new Queue<ProcessControlBlock>(); public CentralProcessUnit() {
LoadPcbList();
}
/// <summary>
/// 生成进程列表
/// </summary>
/// <param name="count">进程数量</param>
public static void GenerateProcessList(int count) { var processListFile = Path.Combine(Environment.CurrentDirectory, "process_list.txt"); var writer = new StreamWriter(processListFile); var rnd = new Random(DateTime.Now.Millisecond); for (var i = 0; i < count; i++) { var runTime = rnd.Next(1, 10);
writer.WriteLine("{0} {1} {2} {3}", i, Math.Pow(2, i), runTime, rnd.Next(0, 4));
}
writer.Close();
} /// <summary>
/// 加载PCB列表
/// </summary>
private void LoadPcbList() { var processListFile = Path.Combine(Environment.CurrentDirectory, "process_list.txt"); var reader = new StreamReader(processListFile); while (!reader.EndOfStream) { var line = reader.ReadLine(); var procInfo = line.Split(' ');
PCBList.Add(new ProcessControlBlock {
ID = int.Parse(procInfo[0]),
ArriveTime = int.Parse(procInfo[1]),
Time = int.Parse(procInfo[2]),
Priority = int.Parse(procInfo[3])
});
}
} /// <summary>
/// CPU运行
/// </summary>
public void Run() { var times = 0; while (true) { // 如果所有进程运行完,则退出循环
if (FinishQueue.Count == PCBList.Count) { break;
} // 遍历所有进程列表
foreach (var p in PCBList) { // 根据进程到达时间判定是否有新进程加入,然后将进程状态设置为就绪
if (p.ArriveTime == times++) {
Console.WriteLine("时间:{0},进程 {1} 到达", times, p.ID);
p.Status = ProcessStatus.Ready;
} // 讲就绪状态进程加入就绪列表
if (p.Status == ProcessStatus.Ready) {// Console.WriteLine("时间:{0},进程 {1} 加入就绪列表", times, p.ID);
ReadyQueue.Enqueue(p);
} // 如果就绪队列为空则进入下一次循环
if (ReadyQueue.Count == 0) {// Console.WriteLine("时间:{0},没有就绪进程,进入下一个循环", times);
continue;
} // 从就绪队列中取出一个进程运行
var currentProcess = ReadyQueue.Dequeue();
Console.WriteLine("时间:{0},运行进程 {1}", times, p.ID);
currentProcess.Run(); // 将运行完毕进程加入完成列表
if (currentProcess.Status == ProcessStatus.Finish) {
Console.WriteLine("时间:{0},进程 {1} 运行完毕,总运行时间:{2}", times, p.ID, p.RunTime);
FinishQueue.Enqueue(currentProcess);
} else
currentProcess.Status = ProcessStatus.Ready;
}
}
}
}
}Main.cs
namespace OperatingSystemExperiment.Exp1{ public class Main
{ public static void Run() {
CentralProcessUnit.GenerateProcessList(5); new CentralProcessUnit().Run();
}
}
}运行结果
生成的
process_list.txt内容:
0 1 8 3 1 2 3 1 2 4 8 0 3 8 6 3 4 16 4 1
作者:画星星高手
链接:https://www.jianshu.com/p/f2e3612f6a4c
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
