C#操作系统实验-进程状态转化实现

操作系统实验报告
安徽师范大学 计算机与信息学院
姓名: XXX 学号: 1911130XXXX 年级专业: 软工二班
实 验 题 目: 实现进程状态转化

【1.需求分析】
利用高级语言编写程序,模拟进程状态转换的过程。
进程的主要状态:就绪、运行、阻塞、终止,状态之间的转换如下图所示:
在这里插入图片描述

(1)输入形式:进程名、运行的时间片数、初始优先级且随时添加新进程。
(2)输出形式:实时输出进程转换的信息。
(3)程序功能:模拟进程状态转换过程。
【2.概要设计】
设计思路:采用可视化的集成开发环境 Visual Studio 2019。编程语言采用 C#。在实验一搭建的交互式实验系统框架的基础上,通过对其中的“进程状态转换”子窗口的编辑完善。
采用进程控制块(PCB)描述一个进程的所有信息包括:进程标识符、处理机状态、进程调度信息以及控制信息,它是系统感知进程存在的唯一标志,进程与 PCB是一一对应的。
对PCB 中的内容在此可做一些简化处理,只包括:进程标识符(内部标识符、外部标识符)、当前状态(“就绪”,“阻塞”,“执行”和“终止”)、要求运行的时间片数、优先级等。
模拟过程
按优先级高低对进程进行调度,每个进程可有四个状态,即:“就绪”,“阻塞”,“执行”和“消亡”(假设优先数越大优先级越高,以及进程的初始状态为就绪状态)。
为便于处理,应该随机地赋予所有进程各自的“优先级”和“要求运行的时间片数”,由用户给定。
程序中共设 4 个队列:就绪队列、执行队列、阻塞队列和消亡队列。
按优先级调度时,进程每运行一次,优先级降低一位,要求的时间片数减 1,如果要求的时间片数为零了,则将其加入终止队列。否则,将其按照优先级的次序重新加入就绪队列。
要求的时间片数为零了,则将其加入终止队列。否则,将其按照优先级的次序重新加入就绪队列。
进程运行过程中,遇到阻塞时,将该进程加入阻塞队列。(通过随机函数得到随机数,满足某种情况则使之加入到阻塞队列,或人为设置是否阻塞)。
重复调度,直到就绪队列中所有进程全部运行结束。

流程图:
在这里插入图片描述

【3.详细设计】
定义的类类型PCB的实现如下:

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

namespace 操作系统实验一
{
    class PCB
    {
        public int Pid //内部标识符
        {
            get;
            set;
        }
        public string Processname  //外部标识符(进程名称)
        {
            get;
            set;
        }
        public int Timeslice //要求运行的时间片数
        {
            get;
            set;
        }

        public int Priority //优先级
        {
            get;
            set;
        }
        public string State //状态
        {
            get;
            set;
        }
    }
}	


本次实验的主要操作代码如下:
随机创建:
在这里插入图片描述

自定义创建:

在这里插入图片描述

运行操作:
在这里插入图片描述
在这里插入图片描述
阻塞操作:
在这里插入图片描述

唤醒操作:
在这里插入图片描述
模拟CPU运行函数timer1_Tick函数
在这里插入图片描述

【4.测试结果】

随机创建几个进程:

在这里插入图片描述

自定义创建:
在这里插入图片描述

在这里插入图片描述

运行:
在这里插入图片描述

阻塞:
在这里插入图片描述

唤醒:
在这里插入图片描述

相关设置:
在这里插入图片描述

可以更换背景颜色
在这里插入图片描述

暂停程序运行(暂停时不能进行其他操作)
在这里插入图片描述

【5.源代码】


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 操作系统实验一
{
    public partial class Form2 : Form
    {
        public int pid = 0;        //进程ID
        public string Processname;   //进程名
        public int Timeslice;   //时间片
        public int Priority;   //优先级
        public int flag = 0;//标志
        public int i = 0;
        public int time1 = 0;
        List<PCB> ready = new List<PCB>();      //就绪队列
        List<PCB> running = new List<PCB>();   //运行队列
        List<PCB> clog = new List<PCB>();     //阻塞队列
        List<PCB> destroy = new List<PCB>();   //消亡队列

        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (ready.Count + running.Count + clog.Count + destroy.Count >= 100) { MessageBox.Show("最多创建100个进程!", "错误"); }
            else
            {
                PCB pcb = new PCB();
                pcb.Pid = ++pid;
                pcb.Processname = this.textBox2.Text;
                pcb.Priority = Convert.ToInt32(this.textBox3.Text);
                pcb.Timeslice = Convert.ToInt32(this.textBox4.Text);
                pcb.State = "就绪";
                ready.Add(pcb);
                ready.Sort(delegate (PCB x, PCB y) //排序
                {
                    return y.Priority.CompareTo(x.Priority);
                });
                string str = "进程" + pcb.Pid + "创建成功!\n";
                richTextBox1.AppendText(str);
                this.dataGridView1.DataSource = new BindingList<PCB>(ready);
                this.textBox2.Text = "";//输入框置空
                this.textBox3.Text = "";//输入框置空
                this.textBox4.Text = "";//输入框置空
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (ready.Count + running.Count + clog.Count + destroy.Count >= 100) { MessageBox.Show("最多创建100个进程!", "错误"); }
            else
            {
                PCB pcb = new PCB();
                pcb.Pid = ++pid;
                Random RA = new Random(); //生成随机数
                pcb.Processname = this.textBox1.Text;
                
                pcb.Timeslice = RA.Next(1, 24);
                pcb.Priority = RA.Next(1, 24)+ pcb.Timeslice;
                pcb.State = "就绪";
                ready.Add(pcb);
                ready.Sort(delegate (PCB x, PCB y) //排序
                {
                    return y.Priority.CompareTo(x.Priority);
                });
                string str = "进程" + pcb.Pid + "创建成功!\n";
                richTextBox1.AppendText(str);
                this.dataGridView1.DataSource = new BindingList<PCB>(ready);
                this.textBox1.Text = ""; 
            }
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            go();//调用运行函数
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (flag == 1)//暂停运行
            {
                MessageBox.Show("运行已暂停,请重新启动!", "错误");
            }
            else if (running.Count == 0)
            {
                MessageBox.Show("运行队列为空,无法阻塞任何进程!", "错误");
            }
            else  //阻塞正在运行的进程
            {
                timer1.Stop();
                running[0].State = "阻塞";
                clog.Add(running[0]);
                richTextBox1.AppendText("进程" + running[0].Pid + "执行--->阻塞\n");
                running.RemoveAt(0);
                this.dataGridView3.DataSource = new BindingList<PCB>(clog);
                this.dataGridView2.DataSource = new BindingList<PCB>(running);
                if (running.Count == 0 && ready.Count != 0) go();

            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (flag == 1)//暂停运行
            {
                MessageBox.Show("运行已暂停,请重新启动!", "错误");
            }
            else if (clog.Count == 0)
            {
                MessageBox.Show("阻塞队列为空,无法唤醒任何进程!", "错误");
            }
            else if (clog.Count > 0) 
            {//唤醒被阻塞进程
                clog[0].State = "就绪";
                ready.Add(clog[0]);
                richTextBox1.AppendText("进程" + clog[0].Pid + "阻塞--->就绪\n");
                clog.RemoveAt(0);
                ready.Sort(delegate (PCB x, PCB y)
                {
                    return y.Priority.CompareTo(x.Priority);
                });
                this.dataGridView1.DataSource = new BindingList<PCB>(ready);
                this.dataGridView3.DataSource = new BindingList<PCB>(clog);
                if (running.Count == 0 && ready.Count != 0) go();
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (running.Count == 1 && running[0].Timeslice > 0) //运行队列为空且未运行完
            {
                running[0].Timeslice--;
                running[0].Priority--;
                this.dataGridView2.DataSource = new BindingList<PCB>(running);
                time1++;
                richTextBox1.AppendText(time1 + "秒过去……\n");
            }
            else if (running.Count == 1 && running[0].Timeslice == 0) //运行队列完成
            {
                running[0].State = "消亡";
                destroy.Add(running[0]);
                richTextBox1.AppendText("进程" + running[0].Pid + "执行--->消亡\n");
                running.RemoveAt(0);
                this.dataGridView4.DataSource = new BindingList<PCB>(destroy);
                this.dataGridView2.DataSource = new BindingList<PCB>(running);
                if (running.Count == 0 && ready.Count != 0) go(); //若运行队列为空且就绪队列还有进程,继续运行进程。
            }
        }
        private void go() //开始
        {
            if(flag == 1)//暂停
            {
                MessageBox.Show("运行已暂停,请重新启动!", "错误");
            }
            else if (ready.Count == 0) //若就绪队列为空,无法执行
            {
                MessageBox.Show("就绪队列为空,无法执行!", "错误");

            }
            else //就绪队列非空
            {
                if (running.Count == 0)
                {
                    ready[0].State = "执行";
                    running.Add(ready[0]);
                    ready.RemoveAt(0);
                    richTextBox1.AppendText("进程" + running[0].Pid + "就绪--->执行\n");
                    this.dataGridView2.DataSource = new BindingList<PCB>(running);
                    this.dataGridView1.DataSource = new BindingList<PCB>(ready);
                    timer1.Start();
                }
            }
        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {            
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.SelectionLength = 0;
            richTextBox1.ScrollToCaret();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (colorDialog1.ShowDialog() == DialogResult.OK)
                {
                      this.BackColor = colorDialog1.Color;
                }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }

        private void 更换背景颜色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (colorDialog1.ShowDialog() == DialogResult.OK)
            {
                this.BackColor = colorDialog1.Color;
            }
        }

        private void 暂停运行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            flag = 1;
    }

        private void 重新启动ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
            flag = 0;
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }
    }
}


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

namespace 操作系统实验一
{
    class PCB
    {
        public int Pid //内部标识符
        {
            get;
            set;
        }
        public string Processname  //外部标识符(进程名称)
        {
            get;
            set;
        }
        public int Timeslice //要求运行的时间片数
        {
            get;
            set;
        }

        public int Priority //优先级
        {
            get;
            set;
        }
        public string State //状态
        {
            get;
            set;
        }
    }
}

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值