C#进程调度的模拟实现:模拟先来先服务调度算法、短作业优先调度算法和优先级调度算法(考虑非抢占式和抢占式),进行算法评价,输出调度结果和算法评价指标。

没什么水平,希望能帮到你

环境:visual studio 2019

附带工程资源:C#进程调度的模拟实现附带资源-C#文档类资源-CSDN下载

先来先服务的调度算法:是一种非抢占式的算法,先来先服务(FCFS: first come first service)总是把当前处于就绪队列之首的那个进程调度到运行状态。也就说,它只考虑进程进入就绪队列的先后,而不考虑它的下一个CPU周期的长短及其他因素。FCFS算法简单易行,是一种非抢占式策略,但性能不大好。

短作业优先调度算法思想:短作业优先调度算法(Short Job First)用于进程调度时又被称为短进程优先调度算法(ShortProcess First),该算法既可以用于作业调度,又可以用于进程调度。在作业调度中,该算法每次从后备作业队列中挑选估计服务时间最短的一个或几个作业,将他们调入内存,分配必要的资源,创建进程并放入就绪队列。在进程调度中的原理类似。SJF是非抢占式的,优先照顾短作业,具有很好的性能,降低平均等待时间,提高吞吐量。但是不利于长作业,长作业可能一直处于等待状态,出现饥饿现象;完全未考虑作业的优先紧迫程度,不能用于实时系统。

优先级调度算法:常用于批处理系统中,在进程调度中,每次调度时,系统把处理机分配给就绪队列中优先数最高的进程,算法又细分为两种:非抢占式优先级算法和抢占式优先级算法。

(1)在非抢占式优先数算法下,系统一旦把处理机分配给就绪队列中优先数最高的进程后,这个进程就会一直运行,直到完成或发生某事件使它放弃处理机,这时系统才能重新将处理机分配给就绪队列中的另一个优先数最高的进程。

(2)在抢占式优先数算法下,系统先将处理机分配给就绪队列中优先数最高的进程度让它运行,但在运行的过程中,如果出现另一个优先数比它高的进程,它就要立即停止,并将处理机分配给新的高优先数进程。

程序大致区分为四部分设计

第一部分:Common区

这里面的类都是整个程序设计的“工具”,一共有三个类存在于此区,分别是PCB定义类,Process定义类和Singleton单例模板工具类。

第二部分:Managers区

这里面的类是为了实现对所有算法的管理而存在的。

第三部分:Algorithms区

这里面的类都是算法的具体实现类,通过与Manager区的管理类相联系实现算法的管理,一共有三个类,分别是FCFS算法定义类,SJF算法定义类和PF算法定义类。

第四部分:Program区

这里面的类是程序的入口类,要完成对算法管理器的初始化和调用。

Common区:

PCB类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Common
{
    class PCB
    {
        public string id;  //  进程ID

        public float reachTime;  //  到达时间

        public float needTime;  //  还需时间

        public float startTime;  //  开始时间

        public float finishTime;  //  完成时间

        public Status state;  //  状态

        public float restTime;  //  剩余时间

        public int priority;

        public enum Status
        {
            Ready = 0,
            Runing = 1,
            Block = 2,
            Destory = 3
        }
    }
}

Process类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Common
{
    class Process
    {
        public string process_id;

        public PCB processPCB;

        public Process(PCB processPCB)
        {
            this.processPCB = processPCB;
            this.process_id = processPCB.id;
        }


    }
}

SingleTon类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Common
{
    public class Singleton where T : new()
    {
        private static T instance;

        public static T Instance
        {
            get
            {
                return Equals(instance, default(T)) ? (instance = new T()) : instance;
            }
        }
    }
}

Managers区:

ProcessManager类

using simulation.Algorithms;
using simulation.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Managers
{
    class ProcessManager : Singleton
    {
        public Dictionary processDictionary = new Dictionary();  //  进程id和PCB字典
        public List processes = new List();  //  所有输入的进程

        public bool PFPreemptive = false;

        public float nowTime;

        public void StartFCFS()
        {
            FCFS.Instance.Init();
            FCFS.Instance.Start();

            PrintOut();
            Console.WriteLine("FCFS Finish");
            Reset();
        }

        public void StartSJF()
        {
            SJF.Instance.Init();
            SJF.Instance.Start();

            PrintOut();
            Console.WriteLine("SJF Finish");
            Reset();
        }

        public void StartPF()
        {
            PF.Instance.Init();
            PF.Instance.Start();

            PrintOut();
            Console.WriteLine("PF Finish");
            Reset();
        }


        public void Reset()
        {
            this.processDictionary.Clear();
            this.processes.Clear();
            this.PFPreemptive = false;
            this.nowTime = 0;
        }

        public void PrintOut()
        {
            //float sum1 = 0.0f, sum2 = 0.0f;
            Console.WriteLine("\n进程  到达时间  运行时间  开始时间  完成时间  周转时间  带权周转时间");
            for (int i = 0;i< processes.Count; i++)
            {
                Console.WriteLine("{0,-4} {1,9:F2} {2,9:F2} {3,9:F2} {4,9:F2} {5,9:F2} {6,9:F2}",
                    processes[i].processPCB.id, processes[i].processPCB.reachTime, processes[i].processPCB.needTime,
                    processes[i].processPCB.startTime, processes[i].processPCB.finishTime, processes[i].processPCB.finishTime - processes[i].processPCB.reachTime,
                    (processes[i].processPCB.finishTime - processes[i].processPCB.reachTime)/ processes[i].processPCB.needTime);
            }
        }


    }
}

Algorithms区:

FCFS类 先来先服务

using simulation.Common;
using simulation.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Algorithms
{
    class FCFS : Singleton
    {

        Comparison FCFSComparison = FCFSCompare;

        private static int FCFSCompare(Process x, Process y)
        {

            return x.processPCB.reachTime.CompareTo(y.processPCB.reachTime);

        }

        public void Init()
        {
            string[] nums;

            Console.WriteLine("进程数:");
            string input = Console.ReadLine();
            Console.WriteLine("收到进程数:{0}",input);
            Console.WriteLine("各进程id、到达时间、运行时间");
            for(int i = 0; i < int.Parse(input); i++)
            {
                string t = Console.ReadLine();
                nums = t.Split(new string(" "), StringSplitOptions.None);

                PCB pCB = new PCB();
                pCB.id = nums[0];
                pCB.reachTime = float.Parse(nums[1]);
                pCB.needTime = float.Parse(nums[2]);

                ProcessManager.Instance.processDictionary.Add(pCB.id, pCB);
                ProcessManager.Instance.processes.Add(new Process(pCB));
            }
        }

        public void Start()
        {
            ProcessManager.Instance.processes.Sort(FCFSComparison);

            List proc = ProcessManager.Instance.processes;

            ProcessManager.Instance.nowTime = proc[0].processPCB.reachTime;

            for (int i =0; i< ProcessManager.Instance.processes.Count;i++)
            {
                if(proc[i].processPCB.reachTime < ProcessManager.Instance.nowTime)
                {
                    proc[i].processPCB.startTime = ProcessManager.Instance.nowTime;
                }
                else
                {
                    proc[i].processPCB.startTime = proc[i].processPCB.reachTime;
                }

                proc[i].processPCB.finishTime = proc[i].processPCB.startTime + proc[i].processPCB.needTime;
                ProcessManager.Instance.nowTime = proc[i].processPCB.finishTime;
            }
        }
    }
}

SJF类 短作业优先调度

using simulation.Common;
using simulation.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Algorithms
{
    class SJF : Singleton
    {

        Comparison SJFReachTimeComparison = SJFReachTimeCompare;
        Comparison SJFNeedTimeComparison = SJFNeedTimeCompare;

        private static int SJFNeedTimeCompare(Process x, Process y)
        {
            return x.processPCB.needTime.CompareTo(y.processPCB.needTime);
        }

        List SJFPreprocesses = new List();
        List SJFAftprocesses = new List();

        private static int SJFReachTimeCompare(Process x, Process y)
        {
            return x.processPCB.reachTime.CompareTo(y.processPCB.reachTime);
        }

        public void Init()
        {
            string[] nums;

            Console.WriteLine("进程数:");
            string input = Console.ReadLine();
            Console.WriteLine("收到进程数:{0}", input);
            Console.WriteLine("各进程id、到达时间、运行时间");
            for (int i = 0; i < int.Parse(input); i++)
            {
                string t = Console.ReadLine();
                nums = t.Split(new string(" "), StringSplitOptions.None);

                PCB pCB = new PCB();
                pCB.id = nums[0];
                pCB.reachTime = float.Parse(nums[1]);
                pCB.needTime = float.Parse(nums[2]);

                ProcessManager.Instance.processDictionary.Add(pCB.id, pCB);
                ProcessManager.Instance.processes.Add(new Process(pCB));
            }
        }

        public void Start()
        {

            ProcessManager.Instance.processes.Sort(SJFReachTimeComparison);

            List proc = ProcessManager.Instance.processes;

            ProcessManager.Instance.nowTime = 0;

            for(int j =0;j< proc.Count; j++)
            {
                for (int i = 0; i < proc.Count; i++)
                {
                    if (proc[i].processPCB.reachTime <= ProcessManager.Instance.nowTime && proc[i].processPCB.finishTime == 0)
                    {
                        SJFPreprocesses.Add(proc[i]);  //  当前时间之前到达的且还未执行的进程放到pre列表里
                    }
                    else if (proc[i].processPCB.reachTime > ProcessManager.Instance.nowTime)
                    {
                        SJFAftprocesses.Add(proc[i]);  //  在当前时间之后到达的进程放在aft列表里
                    }
                }
                SJFPreprocesses.Sort(SJFNeedTimeComparison);  //  前面没执行的的按作业时间
                SJFAftprocesses.Sort(SJFReachTimeComparison);  //  后面的按到达时间

                if (SJFPreprocesses.Count != 0)  //  有当前时间之前到达的进程
                {
                    for (int k = 0; k < proc.Count; k++)
                    {
                        if (proc[k].processPCB.id == SJFPreprocesses[0].processPCB.id)  //  找到这个家伙
                        {
                            proc[k].processPCB.startTime = ProcessManager.Instance.nowTime;
                            proc[k].processPCB.finishTime = proc[k].processPCB.startTime + proc[k].processPCB.needTime;
                            ProcessManager.Instance.nowTime = proc[k].processPCB.finishTime;
                        }
                    }
                }
                else  //  没有当前时间之前到达的进程
                {
                    for (int n = 0; n < proc.Count; n++)
                    {
                        if (proc[n].processPCB.id == SJFAftprocesses[0].processPCB.id)  //  找到这个家伙
                        {
                            proc[n].processPCB.startTime = proc[n].processPCB.reachTime;
                            proc[n].processPCB.finishTime = proc[n].processPCB.startTime + proc[n].processPCB.needTime;
                            ProcessManager.Instance.nowTime = proc[n].processPCB.finishTime;
                        }
                    }
                    //  执行后面第一个
                }
                SJFPreprocesses.Clear();
                SJFAftprocesses.Clear();
            }

    }
}

PF类 优先级调度算法

using simulation.Common;
using simulation.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simulation.Algorithms
{
    class PF : Singleton
    {

        Comparison PFReachTimeComparison = PFReachTimeCompare;
        Comparison PFPriorityAndReachTimeComparison = PFPriorityAndReachTimeCompare;
        //Comparison PFPriorityComparison = PFPriorityCompare;

        //private static int PFPriorityCompare(Process x, Process y)
        //{
        //    return y.processPCB.priority.CompareTo(x.processPCB.priority);
        //}

        private static int PFPriorityAndReachTimeCompare(Process x, Process y)
        {
            if(x.processPCB.priority != y.processPCB.priority)
            {
                return y.processPCB.priority.CompareTo(x.processPCB.priority);
            }
            else
            {
                return x.processPCB.reachTime.CompareTo(y.processPCB.reachTime);
            }

        }

        List PFPreprocesses = new List();
        List PFAftprocesses = new List();

        List proc = ProcessManager.Instance.processes;

        Process runningProcess;
        Process startProcess;
        List blockList = new List();

        private static int PFReachTimeCompare(Process x, Process y)
        {
            return x.processPCB.reachTime.CompareTo(y.processPCB.reachTime);
        }

        public void Init()
        {
            string[] nums;
            string t;

            Console.WriteLine("进程数:");
            string input = Console.ReadLine();
            Console.WriteLine("收到进程数:{0}", input);
            Console.WriteLine("各进程id、到达时间、运行时间、优先级");
            for (int i = 0; i < int.Parse(input); i++)
            {
                t = Console.ReadLine();
                nums = t.Split(new string(" "), StringSplitOptions.None);

                PCB pCB = new PCB();
                pCB.id = nums[0];
                pCB.reachTime = float.Parse(nums[1]);
                pCB.needTime = float.Parse(nums[2]);
                pCB.priority = int.Parse(nums[3]);
                pCB.restTime = pCB.needTime;

                ProcessManager.Instance.processDictionary.Add(pCB.id, pCB);
                ProcessManager.Instance.processes.Add(new Process(pCB));
            }
            Console.WriteLine("抢占式?(Y/N)");
            t = Console.ReadLine();
            if(t == "Y")
            {
                ProcessManager.Instance.PFPreemptive = true;
                for (int i = 0; i < proc.Count; i++)
                {
                    proc[i].processPCB.state = PCB.Status.Ready;
                }
            }

            ProcessManager.Instance.processes.Sort(PFReachTimeComparison);

            ProcessManager.Instance.nowTime = 0;

        }

        public void Start()
        {

            if (ProcessManager.Instance.PFPreemptive)
            {
                PFPreemptiveInit();
                return;
            }

            for (int m =0; m< proc.Count; m++)
            {
                for (int i = 0; i < proc.Count; i++)
                {
                    if (proc[i].processPCB.reachTime <= ProcessManager.Instance.nowTime && proc[i].processPCB.finishTime == 0)
                    {
                        PFPreprocesses.Add(proc[i]);  //  当前时间之前到达的且还未执行的进程放到pre列表里
                    }
                    else if (proc[i].processPCB.reachTime > ProcessManager.Instance.nowTime)
                    {
                        PFAftprocesses.Add(proc[i]);  //  在当前时间之后到达的进程放在aft列表里
                    }
                }

                PFPreprocesses.Sort(PFPriorityAndReachTimeComparison);  //  前面的按优先级和到达时间排
                PFAftprocesses.Sort(PFReachTimeComparison);  //  后面的按到达时间排

                //  非抢占
                if (PFPreprocesses.Count != 0)
                {
                    //  运行列表第一个
                    for (int k = 0; k < proc.Count; k++)
                    {
                        if (proc[k].processPCB.id == PFPreprocesses[0].processPCB.id)  //  找到这个家伙
                        {
                            proc[k].processPCB.startTime = ProcessManager.Instance.nowTime;
                            proc[k].processPCB.finishTime = proc[k].processPCB.startTime + proc[k].processPCB.needTime;
                            ProcessManager.Instance.nowTime = proc[k].processPCB.finishTime;
                        }
                    }
                }
                else
                {
                    //  运行后面列表第一个
                    for (int n = 0; n < proc.Count; n++)
                    {
                        if (proc[n].processPCB.id == PFAftprocesses[0].processPCB.id)  //  找到这个家伙
                        {
                            proc[n].processPCB.startTime = proc[n].processPCB.reachTime;
                            proc[n].processPCB.finishTime = proc[n].processPCB.startTime + proc[n].processPCB.needTime;
                            ProcessManager.Instance.nowTime = proc[n].processPCB.finishTime;
                        }
                    }
                }

                PFPreprocesses.Clear();
                PFAftprocesses.Clear();

            }

        }


        private void PFPreemptiveInit()
        {

            ReFresh();

            if (PFPreprocesses.Count != 0)
            {
                //  运行列表第一个
                for (int k = 0; k < proc.Count; k++)
                {
                    if (proc[k].processPCB.id == PFPreprocesses[0].processPCB.id)  //  找到这个家伙
                    {
                        startProcess = proc[k];
                        RunProcess(proc[k]);  //  让这个进程跑
                        break;
                    }
                }
            }

        }

        private void RunProcess(Process process)
        {
            Console.WriteLine("进程{0}在{1}时刻开始运行", process.processPCB.id, ProcessManager.Instance.nowTime);
            runningProcess = process;
            if(runningProcess.processPCB.startTime == 0 && runningProcess.processPCB.id != startProcess.processPCB.id)
            {
                runningProcess.processPCB.startTime = ProcessManager.Instance.nowTime;
            }
            runningProcess.processPCB.state = PCB.Status.Runing;

            if (IsBlocked())  //  被阻塞了
            {
                RunProcess(runningProcess);
            }
            else  //  没被阻塞
            {
                process.processPCB.finishTime = ProcessManager.Instance.nowTime + process.processPCB.restTime;
                ProcessManager.Instance.nowTime = process.processPCB.finishTime;
                ReFresh();
                process.processPCB.restTime = 0;

                process.processPCB.state = PCB.Status.Destory;
                blockList.Remove(process);
                Console.WriteLine("进程{0}在{1}时刻执行完毕", process.processPCB.id, process.processPCB.finishTime);

                if(blockList.Count != 0)  //  如果有被阻塞的进程
                {
                    blockList.Sort(PFPriorityAndReachTimeComparison);

                    for(int j = 0; j < proc.Count; j++)
                    {
                        if(proc[j].processPCB.id == blockList[0].processPCB.id)
                        {
                            RunProcess(proc[j]);
                            break;
                        }
                    }

                }
                else if(PFAftprocesses.Count != 0)  //  没有被阻塞的进程且后面还有进程,等一段时间后开始
                {
                    ProcessManager.Instance.nowTime = PFAftprocesses[0].processPCB.reachTime;
                    ReFresh();
                    for(int k =0;k < proc.Count; k++)
                    {
                        if(proc[k].processPCB.id == PFAftprocesses[0].processPCB.id)
                        {
                            RunProcess(proc[k]);
                        }
                    }
      
                }
                else
                {
                    Console.WriteLine("所有进程执行完毕");
                }


            }

        }

        public bool IsBlocked()
        {
            for(int i = 0; i< PFAftprocesses.Count; i++)
            {
                if ((PFAftprocesses[i].processPCB.reachTime
                <= runningProcess.processPCB.startTime + runningProcess.processPCB.restTime)
                && PFAftprocesses[i].processPCB.priority > runningProcess.processPCB.priority)  //  不到正在运行进程执行完新进程就会进入且新进程优先级更高
                {
                    runningProcess.processPCB.restTime = runningProcess.processPCB.restTime - (PFAftprocesses[i].processPCB.reachTime - runningProcess.processPCB.startTime);
                    runningProcess.processPCB.state = PCB.Status.Block;
                    blockList.Add(runningProcess);
                    Console.WriteLine("进程{0}在{1}时刻被进程{2}阻塞,restTime:{3}", runningProcess.processPCB.id, PFAftprocesses[i].processPCB.reachTime, PFAftprocesses[i].processPCB.id, runningProcess.processPCB.restTime);


                    for(int n = 0; n < proc.Count; n++)
                    {
                        if (proc[n].processPCB.id == PFAftprocesses[i].processPCB.id)
                        {
                            runningProcess = proc[n];
                            break;
                        }
                    }
                    runningProcess.processPCB.state = PCB.Status.Runing;
                    ProcessManager.Instance.nowTime = runningProcess.processPCB.reachTime;
                    ReFresh();
                    return true;
                }else if ((PFAftprocesses[i].processPCB.reachTime
                <= runningProcess.processPCB.startTime + runningProcess.processPCB.restTime)
                && PFAftprocesses[i].processPCB.priority <= runningProcess.processPCB.priority)   //  不到正在运行进程执行完新进程就会进入但是优先级不足以抢断
                {
                    for (int n = 0; n < proc.Count; n++)
                    {
                        if (proc[n].processPCB.id == PFAftprocesses[i].processPCB.id)
                        {
                            proc[n].processPCB.state = PCB.Status.Block;
                            blockList.Add(proc[n]);
                            Console.WriteLine("进程{0}在时刻{1}尝试抢断失败,进入阻塞状态", proc[n].processPCB.id, proc[n].processPCB.reachTime);
                        }
                    }
                }
            }

            return false;
        }


        public void ReFresh()
        {
            PFPreprocesses.Clear();
            PFAftprocesses.Clear();

            for (int i = 0; i < proc.Count; i++)
            {
                if (proc[i].processPCB.reachTime <= ProcessManager.Instance.nowTime && proc[i].processPCB.restTime != 0)
                {
                    PFPreprocesses.Add(proc[i]);  //  当前时间之前到达的且还未执行完毕的进程放到pre列表里
                }
                else if (proc[i].processPCB.reachTime >= ProcessManager.Instance.nowTime)
                {
                    PFAftprocesses.Add(proc[i]);  //  在当前时间及之后到达的进程放在aft列表里
                }
            }
        }


    }
}

Program区:

Program类

using simulation.Managers;
using System;

namespace simulation
{
    class Program
    {
        bool doItAngin;

        static void Main(string[] args)
        {
            Program program = new Program();
            program.NewMethod();

        }

        private void NewMethod()
        {
            doItAngin = true;

            do
            {
                Console.WriteLine("1:先来先服务调度算法,2:短作业优先调度算法,3:优先级调度算法, 退出:Exit");
                string input = Console.ReadLine();
                switch (input)
                {
                    case "1":
                        ProcessManager.Instance.StartFCFS();
                        break;
                    case "2":
                        ProcessManager.Instance.StartSJF();
                        break;
                    case "3":
                        ProcessManager.Instance.StartPF();
                        break;
                    case "Exit":
                        doItAngin = false;
                        break;
                    default:
                        Console.WriteLine("输入错误,请输入三个数字之一或Exit");
                        break;
                }
            } while (doItAngin);
        }
    }
}

使用方法:

C#进程调度的模拟实现:模拟先来先服务调度算法、短作业优先调度算法和优先级调度算法(考虑非抢占式和抢占式),进行算法评价,输出调度结果和算法评价指标。_第1张图片

你可能感兴趣的:(操作系统,c#,开发语言,算法)