Unity也能写操作系统?进来看看

Unity模拟操作系统&&按优先数调度算法实现处理器调度(总代码在文末)

在这里插入图片描述
在这里插入图片描述

众所周知,Unity是一个游戏引擎,它已经是在底层上做了很多封装的结果,那么用Unity写操作系统肯定就是不可能的,但是我这里尝试用Unity模拟一些操作系统中的算法,调度,主要是熟悉Unity开发以及学习C#中的一些算法,话不多说,直入主题----

题目要求

假定系统有5个进程,每个进程用一个PCB来代表。PCB的结构为:
·进程名——如P1~P5。
·指针——按优先数的大小把5个进程连成队列,用指针指出下一个进程PCB的首地址。
·要求运行时间——假设进程需要运行的单位时间数。
·优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
·状态——假设两种状态:就绪和结束,用R表示就绪,用E表示结束。初始状态都为就绪状态。
(2) 开始运行之前,为每个进程确定它的“优先数”和“要求运行时间”。通过键盘输入这些参数。
(3) 处理器总是选择队首进程运行。采用动态改变优先数的办法,进程每运行1次,优先数减1,要求运行时间减1。
(4) 进程运行一次后,若要求运行时间不等于0,则将它加入就绪队列,否则,将状态改为“结束”,退出就绪队列。
(5) 若就绪队列为空,结束,否则转到(3)重复。
要求能接受键盘输入的进程优先数及要求运行时间,能显示每次进程调度的情况,如哪个进程在运行,哪些进程就绪,就绪进程的排列情况。

操作系统中的算法解读

在作业调度中,从后备作业队列中选择若干优先级高的作业调入内存。
在进程调度中,将处理机分配给就绪队列中优先级最高的进程。
优先级(Priority)表示进程的重要性及运行优先性,通常用优先数来衡量。在某些系统中,优先数越大优先级越高;而在另一些系统中,优先数越大优先级越小。
非抢占式优先级调度算法:系统一旦将处理机分配给就绪队列中优先级最高的进程后,该进程便一直运行下去,直到完成或因发生某事件使该进程放弃处理机时,系统才将处理机分配给另一个更高优先级的进程。
抢占式优先级调度算法:将处理机分配给优先级最高的进程,使之运行。在进程运行过程中,一旦出现了另一个优先级更高的进程时,进程调度程序就停止原运行进程,而将处理机分配给新出现的高优先级进程。
也就是说,进程的属性优先级,决定谁先运行,运行结束后改动优先级,然后再找出最高的优先级,此文,优先级数字大的先运行

分析问题

首先,上题中的PCB结构,也就是进程结构,里面有指针,我们这里不用指针,但是我们要达到要求,所以分析一下要求–
要求能接受键盘输入的进程优先数及要求运行时间,能显示每次进程调度的情况,如哪个进程在运行,哪些进程就绪,就绪进程的排列情况。
所以我们需要PCB进程类,类包括优先级,剩余时间,名字这些属性,这些进程还要每隔一段时间排序,这里选择的数据结构是LIST,当然不一定是最优,后面会尝试选择其他容器。

知识点1(本文中能学到的)

IComparable接口

如果一个类实现了 IComparable,那么它就要重写CompareTo方法,这个方法直接决定了如果把这个类装进LIST内,LIST的SORT函数用什么规则比较。
所以我们的进程类要实现这个接口,并且重写CompareTo,让规则变为sort后优先级最高的在LIST前面
类创建代码

public  class Courses: System.IComparable<Courses>
{
    public Courses(string courseName,int priorityNum,int time)
    {
        CourseName = courseName;
        PriorityNum = priorityNum;
        Time = time;
        state = State.Ready;
    }
    //按照PriorityNum排序,此接口方法当返回值大于0的时候,定义的是此对象大,有规则后,List.sort直接按照此规则排序
    public int CompareTo(Courses courses)
    {
        return courses.PriorityNum-this.PriorityNum ;
    }
    public string CourseName;
    public int PriorityNum;
    public int Time;
    public  enum State
    {
        Ready,
        End
    }
    public State state;

}

知识点2(本文中能学到的)

Prefab预制体的生成位置自定义,生成后的属性代码定义

我们的程序每次运行显示都要动态刷新,那么怎么刷新,就是每次排完序动态生成预制体,那么怎么让预制体内的文字改变呢——
在这里插入图片描述
我们的预制体是三个文本框,操作他的方法就是预制体生成的时候,生成到一个Gameobject LIST内,然后取第一个Child,第二个,第三个
刷新函数–

for (int i=0;i<TCourses.Count;i++)
        {
            Ans.Add(Instantiate(One, T[i].position, transform.rotation, Parent));
            Ans[Ans.Count - 1].transform.GetChild(0).GetComponent<Text>().text = "进程名:" + TCourses[i].CourseName.ToString();
            Ans[Ans.Count - 1].transform.GetChild(1).GetComponent<Text>().text = "优先数:" + TCourses[i].PriorityNum.ToString();
            Ans[Ans.Count - 1].transform.GetChild(2).GetComponent<Text>().text = "剩余时间:" + TCourses[i].Time.ToString();
        }

总体实现

代码挂在Canvas上
在这里插入图片描述

挂在模拟运行按钮上的函数
 public  void StartRunButtonPressed()
    {
       
        foreach (GameObject Inputs in InputF)
        {
            if (Inputs.transform.GetChild(0).GetComponent<InputField>().text == "" || Inputs.transform.GetChild(1).GetComponent<InputField>().text == "" || Inputs.transform.GetChild(2).GetComponent<InputField>().text == "")
                ErrorPanel.SetActive(true);
            else
                continue;
        }
        if (isfirst)
        {
            foreach (GameObject Inputs in InputF)
            {
                TCourses.Add(new Courses(Inputs.transform.GetChild(0).GetComponent<InputField>().text, int.Parse(Inputs.transform.GetChild(1).GetComponent<InputField>().text), int.Parse(Inputs.transform.GetChild(2).GetComponent<InputField>().text)));

            }
            isfirst = false;
        }

        Simulation();



    }
排序刷新函数
  public void Simulation()
    {
        foreach(GameObject a in Ans)
        {
            Destroy(a);
        }
        Ans.Clear();
        
        if (TCourses.Count == 0)
        {
            Debug.LogError(1);
            return;
        }

        TCourses.Sort();

        foreach (Courses c in TCourses)
        {
            if (c.Time == 0)
            {
                c.state = Courses.State.End;
                TCourses.Remove(c);
            }
        }
        TCourses[0].PriorityNum -= 1;
        TCourses[0].Time -= 1;


        for (int i=0;i<TCourses.Count;i++)
        {
            Ans.Add(Instantiate(One, T[i].position, transform.rotation, Parent));
            Ans[Ans.Count - 1].transform.GetChild(0).GetComponent<Text>().text = "进程名:" + TCourses[i].CourseName.ToString();
            Ans[Ans.Count - 1].transform.GetChild(1).GetComponent<Text>().text = "优先数:" + TCourses[i].PriorityNum.ToString();
            Ans[Ans.Count - 1].transform.GetChild(2).GetComponent<Text>().text = "剩余时间:" + TCourses[i].Time.ToString();
        }
      


        if (TCourses[0].Time == 0)
        {
            TCourses.RemoveAt(0);
           
        }
      
    }
总函数
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//进程数据类型
public  class Courses: System.IComparable<Courses>
{
    public Courses(string courseName,int priorityNum,int time)
    {
        CourseName = courseName;
        PriorityNum = priorityNum;
        Time = time;
        state = State.Ready;
    }
    //按照PriorityNum排序,此接口方法当返回值大于0的时候,定义的是此对象大,有规则后,List.sort直接按照此规则排序
    public int CompareTo(Courses courses)
    {
        return courses.PriorityNum-this.PriorityNum ;
    }
    public string CourseName;
    public int PriorityNum;
    public int Time;
    public  enum State
    {
        Ready,
        End
    }
    public State state;

}
public class quiz1 : MonoBehaviour
{ 
    public bool  isfirst;
    public GameObject ErrorPanel;
    public GameObject One;
  
    public List<GameObject>Ans;
    public Transform Parent;
    public List<RectTransform> T;
   
    //存贮所有的进程
    public List<GameObject> InputF ;
    public List<Courses> TCourses;
   
    void Awake()
    {
        isfirst = true;
        //T = new List<RectTransform>();
        TCourses = new List<Courses>();
        Ans = new List<GameObject>();
    }
  

    public  void StartRunButtonPressed()
    {
       
        foreach (GameObject Inputs in InputF)
        {
            if (Inputs.transform.GetChild(0).GetComponent<InputField>().text == "" || Inputs.transform.GetChild(1).GetComponent<InputField>().text == "" || Inputs.transform.GetChild(2).GetComponent<InputField>().text == "")
                ErrorPanel.SetActive(true);
            else
                continue;
        }
        if (isfirst)
        {
            foreach (GameObject Inputs in InputF)
            {
                TCourses.Add(new Courses(Inputs.transform.GetChild(0).GetComponent<InputField>().text, int.Parse(Inputs.transform.GetChild(1).GetComponent<InputField>().text), int.Parse(Inputs.transform.GetChild(2).GetComponent<InputField>().text)));

            }
            isfirst = false;
        }

        Simulation();



    }
    
    public void Simulation()
    {
        foreach(GameObject a in Ans)
        {
            Destroy(a);
        }
        Ans.Clear();
        
        if (TCourses.Count == 0)
        {
            Debug.LogError(1);
            return;
        }

        TCourses.Sort();

        foreach (Courses c in TCourses)
        {
            if (c.Time == 0)
            {
                c.state = Courses.State.End;
                TCourses.Remove(c);
            }
        }
        TCourses[0].PriorityNum -= 1;
        TCourses[0].Time -= 1;


        for (int i=0;i<TCourses.Count;i++)
        {
            Ans.Add(Instantiate(One, T[i].position, transform.rotation, Parent));
            Ans[Ans.Count - 1].transform.GetChild(0).GetComponent<Text>().text = "进程名:" + TCourses[i].CourseName.ToString();
            Ans[Ans.Count - 1].transform.GetChild(1).GetComponent<Text>().text = "优先数:" + TCourses[i].PriorityNum.ToString();
            Ans[Ans.Count - 1].transform.GetChild(2).GetComponent<Text>().text = "剩余时间:" + TCourses[i].Time.ToString();
        }
      


        if (TCourses[0].Time == 0)
        {
            TCourses.RemoveAt(0);
           
        }
      
    }

  
}

结果

在这里插入图片描述
感觉写的还行的不要吝啬一个赞哟,是对码农最大的鼓励

原创文章 66 获赞 39 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44739495/article/details/105846902