为了账号安全,请及时绑定邮箱和手机立即绑定

操作系统学习一:.NetCore 实现模拟多道程序设计的简单处理机调用

标签:
Java

前言

道程序设计中,经常是若干个进程同时处于就绪状态,为了使系统中的各进程有条不紊地运行,必须选择某种调度策略,以选择一个进程占用处理机。本次实验设计一个模拟单处理机调度的算法,以加深对处理机调度算法的理解。

要求

  1. 按照时间片轮转算法设计模拟调度程序。

  2. 输出进程的调度过程。

思路分析

由于本实验是按照处理机调度算法模拟实现处理机的调度,与真正的处理机调度过程并不完全相同,比如没有实现中断(时间片设为1),进程的运行也不是真正的运行,而是在屏幕上打印其运行时间等。所以要以文件的形式给出进程的信息,文件信息可参考如下:

进程ID  到达时间     估计运行时间     优先级
0        0             3               2
1        2             6               4
2        4             4               0
3        6             5               3
4        8             2               1

以下是实验的大致思路:

  1. 建立三个队列:PCB队列,就绪队列,完成队列。
    PCB队列:保存将进入系统的进程。(由于没有实现中断,所以将进入系统运行的进程必须在程序运行前给出)。
    就绪队列:到达进程进入系统的时间,将该进程放入就绪队列,等待调度。
    完成队列:将“运行”完的进程放入完成队列。

  2. 进程运行过程是在屏幕上打印相关信息。
    使用轮转算法调度的进程应打印的信息包括:进程占用处理机序列,该进程每次占用处理机的开始时间与结束时间。

  3. 统计出进程的周转时间T和带权周转时间W。

流程图

webp

实现代码

  1. 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);
    }
}
  1. 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;
                }
            }
        }
    }
}
  1. 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 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消