道程序設計中,常常是若干個進程同時處於就緒狀態,爲了使系統中的各進程有條不紊地運行,必須選擇某種調度策略,以選擇一個進程佔用處理機。本次實驗設計一個模擬單處理機調度的算法,以加深對處理機調度算法的理解。算法
因爲本實驗是按照處理機調度算法模擬實現處理機的調度,與真正的處理機調度過程並不徹底相同,好比沒有實現中斷(時間片設爲1),進程的運行也不是真正的運行,而是在屏幕上打印其運行時間等。因此要以文件的形式給出進程的信息,文件信息可參考以下:微信
進程ID 到達時間 估計運行時間 優先級 0 0 3 2 1 2 6 4 2 4 4 0 3 6 5 3 4 8 2 1
如下是實驗的大體思路:dom
PCB隊列:保存將進入系統的進程。(因爲沒有實現中斷,因此將進入系統運行的進程必須在程序運行前給出)。
就緒隊列:到達進程進入系統的時間,將該進程放入就緒隊列,等待調度。
完成隊列:將「運行」完的進程放入完成隊列。ide
使用輪轉算法調度的進程應打印的信息包括:進程佔用處理機序列,該進程每次佔用處理機的開始時間與結束時間。this
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); } }
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; } } } } }
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
時間:1,運行進程 0
時間:2,運行進程 1
時間:3,運行進程 2
時間:4,運行進程 3
時間:5,運行進程 4
時間:6,運行進程 0
時間:7,運行進程 1
時間:8,運行進程 2
時間:9,進程 3 到達
時間:9,運行進程 3
時間:10,運行進程 4
時間:11,運行進程 0
時間:12,運行進程 1
時間:13,運行進程 2
時間:14,運行進程 3
時間:15,運行進程 4
時間:16,運行進程 0
時間:17,運行進程 1
時間:17,進程 1 運行完畢,總運行時間:3
時間:18,運行進程 2
時間:19,運行進程 3
時間:20,運行進程 4
時間:21,運行進程 0
時間:23,運行進程 2
時間:24,運行進程 3
時間:25,運行進程 4
時間:25,進程 4 運行完畢,總運行時間:4
時間:26,運行進程 0
時間:28,運行進程 2
時間:29,運行進程 3
時間:31,運行進程 0
時間:33,運行進程 2
時間:34,運行進程 3
時間:34,進程 3 運行完畢,總運行時間:6
時間:36,運行進程 0
時間:38,運行進程 2
時間:41,運行進程 0
時間:41,進程 0 運行完畢,總運行時間:8
時間:43,運行進程 2
時間:43,進程 2 運行完畢,總運行時間:8spa
瞭解更多有趣的操做請關注個人微信公衆號:DealiAxy
每一篇文章都在個人博客有收錄:blog.deali.cn設計