2017年3月 操作系统课程设计作品:磁盘调度算法模拟
目的:了解磁盘管理的原理,掌握磁盘调度种算法。
设计要求:编程序实现下述磁盘调度算法,并求出每种算法的平均寻道长度:要求设计主界面可以灵活选择算法,且以下算法都要实现。
(1) 先来先服务算法(FCFS)
(2) 最短寻道时间优先算法(SSTF)
(3) 扫描算法(SCAN)
(4) 循环扫描算法(CSCAN)
主要实现了几个算法的模拟,在界面设计上使用了VS2015的可视化拖动控件,可视化展示窗口中为了实现绘制图表需要引用OWC控件,微软官方下载地址:https://www.microsoft.com/zh-cn/download/details.aspx?id=22276
成果界面展示:
using Microsoft.Office.Interop.Owc11;
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 DiskManager1
{
public partial class diskManager : Form
{
public diskManager()
{
InitializeComponent();
}
int MAX_INT = 0x3f3f3f3f;
int origin;
struct DiskRequest
{
public int p;
public int visit;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
private void label4_Click(object sender, EventArgs e)
{
}
private void label4_Click_1(object sender, EventArgs e)
{
}
private void panel3_Paint(object sender, PaintEventArgs e)
{
}
private void label6_Click(object sender, EventArgs e)
{
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
}
private void numericUpDown1_ValueChanged_1(object sender, EventArgs e)
{
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
public static bool Delay(int delayTime)
{
DateTime now = DateTime.Now;
int s;
do
{
TimeSpan spand = DateTime.Now - now;
s = spand.Seconds;
Application.DoEvents();
}
while (s < delayTime);
return true;
}
void generate(int[] data,int total,int n)
{
ChartSpaceClass mySpace = new ChartSpaceClass();
ChChart ChartDisk = mySpace.Charts.Add(0);
ChartDisk.Type = ChartChartTypeEnum.chChartTypeLineMarkers;
ChartDisk.HasTitle = true;
ChartDisk.Title.Font.Size = 12;
ChartDisk.Title.Font.Color = "ff3300";
ChartDisk.Axes[0].HasTitle = true;
ChartDisk.Axes[0].Title.Caption = "访问序列";
ChartDisk.Axes[1].HasTitle = true;
ChartDisk.Axes[1].Title.Caption = "地址";
ChartDisk.Axes[0].Title.Font.Bold = ChartDisk.Axes[1].Title.Font.Bold = true;
ChartDisk.Axes[0].Title.Font.Color = ChartDisk.Axes[1].Title.Font.Color = "#994400";
string[] DataName = new string[n+1];
ChartDisk.Title.Caption = "总移动磁道数:" + total.ToString();
for(int k=0;k<=n;k++)
{
for (int i = 0; i <= k; i++)
{
DataName[i] = string.Format("{0:" + string.Format("{0:D2}", i) + "\r\n月\r\n" + "}", i.ToString());
}
string strValue = "";
string strCategory = "";
for (int i = 0; i <= k; i++)
{
//
strCategory += DataName[i] + '\t';
strValue += data[i].ToString() + '\t';
}
ChartDisk.SeriesCollection.Add(0);
ChartDisk.SeriesCollection[0].SetData(ChartDimensionsEnum.chDimSeriesNames,
(int)ChartSpecialDataSourcesEnum.chDataLiteral, "地址");
ChartDisk.SeriesCollection[0].SetData(ChartDimensionsEnum.chDimCategories,
(int)ChartSpecialDataSourcesEnum.chDataLiteral, strCategory);
ChartDisk.SeriesCollection[0].SetData(ChartDimensionsEnum.chDimValues,
(int)ChartSpecialDataSourcesEnum.chDataLiteral, strValue);
string strAbsolutePath = Application.StartupPath + @"\Images\rate.gif";
mySpace.ExportPicture(strAbsolutePath, "GIF", pictureBox1.Width, pictureBox1.Height);
pictureBox1.ImageLocation = strAbsolutePath;
Delay(1);
}
}
private void button1_Click(object sender, EventArgs e)
{
int Request_num = Int32.Parse(this.numericUpDown1.Value.ToString());
if(Request_num != richTextBox1.Lines.Length)
{
MessageBox.Show("访问序列(" + richTextBox1.Lines.Length.ToString() + ")与请求数量(" + Request_num.ToString() + ")在数值上不一致!");
return;
}
int pos = Int32.Parse(this.numericUpDown2.Value.ToString());
int[] data = new int[Request_num+1];
origin = pos;
data[0] = pos;
DiskRequest[] seq = new DiskRequest[Request_num];
for(int i=0;i"+seq[i].p.ToString();
data[i + 1] = seq[i].p;
}
generate(data, AccumT, Request_num);
textBox2.Text = AccumT.ToString();
textBox3.Text = (Double.Parse(AccumT.ToString()) / Request_num).ToString("0.00");
}
private void button2_Click(object sender, EventArgs e)
{
int Request_num = Int32.Parse(this.numericUpDown1.Value.ToString());
if (Request_num != richTextBox1.Lines.Length)
{
MessageBox.Show("访问序列(" + richTextBox1.Lines.Length.ToString() + ")与请求数量(" + Request_num.ToString() + ")在数值上不一致!");
return;
}
int pos = Int32.Parse(this.numericUpDown2.Value.ToString());
int[] data = new int[Request_num + 1];
origin = pos;
data[0] = pos;
DiskRequest[] seq = new DiskRequest[Request_num];
for (int i = 0; i < Request_num; i++)
{
seq[i].p = Int32.Parse(this.richTextBox1.Lines[i]);
seq[i].visit = 0;
}
textBox1.Text = pos.ToString();
int AccumT = 0;
int flag = Request_num, current = pos,t=1;
while (flag-->0)
{
int temp = current - MAX_INT, p = 0;
for(int i=0;i" + current.ToString();
}
generate(data, AccumT, Request_num);
textBox2.Text = AccumT.ToString();
textBox3.Text = (Double.Parse(AccumT.ToString()) / Request_num).ToString("0.00");
}
bool cmp1(DiskRequest a,DiskRequest b)
{
if ((a.p - origin) * (b.p - origin) == 0) return a.p == origin;//如果两者之中有地址与初始地址相同的,则将初始地址放在前面
else if ((a.p - origin) * (b.p - origin) < 0) return a.p > b.p;//如果两者在初始地址的左右两边,则返回大于初始地址的地址
else
{
if (a.p < origin) return a.p > b.p;//如果两个地址在初始地址的右边,返回大地址
else return a.p < b.p;//如果两个地址在初始地址的左边,返回小地址
}
}
private void button3_Click(object sender, EventArgs e)
{
int Request_num = Int32.Parse(this.numericUpDown1.Value.ToString());
if (Request_num != richTextBox1.Lines.Length)
{
MessageBox.Show("访问序列(" + richTextBox1.Lines.Length.ToString() + ")与请求数量(" + Request_num.ToString() + ")在数值上不一致!");
return;
}
int pos = Int32.Parse(this.numericUpDown2.Value.ToString());
int[] data = new int[Request_num + 1];
origin = pos;
data[0] = pos;
DiskRequest[] seq = new DiskRequest[Request_num];
for (int i = 0; i < Request_num; i++)
{
seq[i].p = Int32.Parse(this.richTextBox1.Lines[i]);
seq[i].visit = 0;
}
textBox1.Text = pos.ToString();
int AccumT = 0;
int max = -1, min = MAX_INT;
for(int i=0;i max) max = seq[i].p;
if (seq[i].p < min) min = seq[i].p;
}
for(int i=0;i" + seq[i].p;
data[i + 1] = seq[i].p;
}
//AccumT = 2 * (max - pos) + (pos - min);
generate(data, AccumT, Request_num);
textBox2.Text = AccumT.ToString();
textBox3.Text = (Double.Parse(AccumT.ToString()) / Request_num).ToString();//"0.00");
}
//CSCAN循环扫描调度算法的排序规则
bool cmp3(DiskRequest a,DiskRequest b)
{
if ((a.p - origin) * (b.p - origin) == 0) return a.p == origin;//如果两者之中有地址与初始地址相同的,则将初始地址放在前面
else if ((a.p - origin) * (b.p - origin) < 0) return a.p > b.p;//如果两者在初始地址的左右两边,则返回大于初始地址的地址
else return a.p < b.p;//如果两个地址在初始地址的同一边,返回小地址
}
private void button4_Click(object sender, EventArgs e)
{
int Request_num = Int32.Parse(this.numericUpDown1.Value.ToString());
if (Request_num != richTextBox1.Lines.Length)
{
MessageBox.Show("访问序列("+richTextBox1.Lines.Length.ToString()+")与请求数量("+Request_num.ToString()+")在数值上不一致!");
return;
}
int pos = Int32.Parse(this.numericUpDown2.Value.ToString());
int[] data = new int[Request_num + 1];
origin = pos;
data[0] = pos;
DiskRequest[] seq = new DiskRequest[Request_num];
for (int i = 0; i < Request_num; i++)
{
seq[i].p = Int32.Parse(this.richTextBox1.Lines[i]);
seq[i].visit = 0;
}
textBox1.Text = pos.ToString();
int AccumT = 0;
int max = -1, min = MAX_INT;
for (int i = 0; i < Request_num; i++)
{
if (seq[i].p > max) max = seq[i].p;
if (seq[i].p < min) min = seq[i].p;
}
for (int i = 0; i < Request_num - 1; i++)
{
for (int j = 0; j < Request_num - 1 - i; j++)
{
if (!cmp3(seq[j], seq[j + 1]))
{
int temp = seq[j].p;
seq[j].p = seq[j + 1].p;
seq[j + 1].p = temp;
}
}
}
AccumT += Math.Abs(seq[0].p - pos) % max;
for (int i = 0; i < Request_num; i++)
{
if (i + 1 < Request_num)
AccumT += Math.Abs(seq[i + 1].p - seq[i].p) % max;
textBox1.Text += "->" + seq[i].p;
data[i + 1] = seq[i].p;
}
//AccumT = 2 * (max - min)-(pos - seq[Request_num-1].p);
generate(data, AccumT, Request_num);
textBox2.Text = AccumT.ToString();
textBox3.Text = (Double.Parse(AccumT.ToString()) / Request_num).ToString("0.00");
}
private void textBox1_TextChanged_1(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
private void textBox4_TextChanged_1(object sender, EventArgs e)
{
}
private void textBox5_TextChanged(object sender, EventArgs e)
{
}
private void label7_Click(object sender, EventArgs e)
{
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void pictureBox1_Click_1(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
{
}
}
}