进程调度
1.编程语言:Java
2.进程调度示意图
3.采用java实现进程调度的总体思路
利用java是一门面向对象的语言,创建PCB类,在类中定义成员变量和成员方法。创建Arraylist类(对象数组)对象(就绪队列、运行队列、完成队列),类型是PCB,用来存储进程。在main方法中定义方法分别实现调度算法,用switch/case
来选择调度算法。if
语句来判断就绪队列是否为空,如果不为空则进程调度,给进程分配CPU;用if
语句判断运行运行队列是否为空,如果为不为空继续判断运行进程的I/O请求时间是否到,如果请求时间到了,则进入阻塞队列否则运行时间+1,如果运行进程的运行时间已用完,则该进程已完成,释放CPU。用if
语句判断阻塞队列是否为空,如果不为空,则继续判断阻塞队列中的进程I/O操作完成,如果完成则进入就绪队列,否则阻塞时间+1。
4.流程图
5.代码解释
代码中写了两个类,分别是Main、TestGUI;TestGUI是用来展示界面的,运行的时候只需要运行Main这个类
在Main类中有5点是比较重要的,分别是:PCB类、调度算法池、进程创建按钮监听方法、时间+1按钮监听方法、重置按钮监听方法,下面分别介绍。
-
PCB类
//PCB类 public static class PCB{ String name;//进程名称 String state;//进程状态 int runtime;//运行的时间 int UsedCPU;//已用CPU时间 int CPUTime;//需要CPU运行时间 int IOTime;// I/O需求时间 int Priority; //优先级 int WaitIO;// 请求I/O所耗的时间 int rank;// 进程到达就绪队列的排名 //以进程的排名进行排序 public static Comparator<PCB> rankComparator = new Comparator<PCB>() { public int compare(PCB pcb1, PCB pcb2) { int rank1 = pcb1.rank; int rank2 = pcb2.rank; return rank1-rank2; }}; //以进程作业大小进行排序 public static Comparator<PCB> CPUTimeComparator = new Comparator<PCB>() { public int compare(PCB pcb1, PCB pcb2) { int CPUTime1 = pcb1.CPUTime; int CPUTime2 = pcb2.CPUTime; return CPUTime1-CPUTime2; }}; //以进程的优先级来进行排序 public static Comparator<PCB> PriorityComparator = new Comparator<PCB>() { public int compare(PCB pcb1, PCB pcb2) { int Priority1 = pcb1.Priority; int Priority2 = pcb2.Priority; return Priority1-Priority2; }}; }
-
在PCB类中,主要看这几个成员变量:name、state、UsedCPU、CPUTime、IOTime、Priority、WaitIO、rank。
-
成员方法是为了根据的不同成员变量来对进程进行排序来编写的,因为在arraylist中,它有.sort()这个方法,如果arraylist存储数值,那么这个方法是有用的。但存储的是对象,这个方法是没用的。我们想根据对象的属性值来对arraylist里对象进行排序,那该怎么办呢?其实java非常强大,它有Comparable接口***,可以自定义一个实例化的比较器(Comparator),重写里面的compare方法,上面就是创建三个比较器,重写里面的
compare
方法。==这里再补充一点,类里面添加static*其实就是定义静态方法,这样就不需要创建对象,我们也能使用类中的方法。==
-
-
调度算法池
//调度算法池 public static void SchedulingAlgorithmPool(TestGUI GUI,ArrayList<PCB>ReadyQueue) { if(GUI.type>=0) { switch(GUI.type) { //先来先服务(FCFS)算法 case 0: FCFS(ReadyQueue); //短进程优先算法(SPF) case 1: SPF(ReadyQueue); //优先级调度算法(PSA) case 2: PSA(ReadyQueue); } } }
这个很容易看懂,就不介绍了哈😄
这是调度算法
//先来先服务(FCFS)算法
public static void FCFS(ArrayList<PCB>ReadyQueue)
{
Collections.sort(ReadyQueue,PCB.rankComparator);
}
//短作业优先算法(SJF)
public static void SPF(ArrayList<PCB>ReadyQueue)
{
Collections.sort(ReadyQueue,PCB.CPUTimeComparator);
}
//优先级调度算法(PSA)
public static void PSA(ArrayList<PCB>ReadyQueue)
{
Collections.sort(ReadyQueue,PCB.PriorityComparator);
}
这里需要结合上面的PCB类,上面定义了三个比较器,那么如何对arraylist中的对象进行排序呢,其实java有一个Collections类,那里面有.sort()方法,可以将arraylist的对象和比较器输入进去,这样就可以对arraylist中的对象进行排序,怎么样这种是不是很666
-
进程创建按钮监听方法
//进程创建按钮监听方法 GUI.btn3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(GUI.txtfield1.getText().length()==0&&GUI.txtfield2.getText().length()==0&&GUI.txtfield3.getText().length()==0&&GUI.txtfield4.getText().length()==0) JOptionPane.showMessageDialog(null, "请填写进程PCB中的信息!!!", "错误 ", 0); else { GUI.i++; PCB pcb=new PCB(); pcb.name="PCB"+GUI.i; pcb.state="就绪"; pcb.CPUTime=Integer.parseInt(GUI.txtfield1.getText()); pcb.UsedCPU= pcb.CPUTime; pcb.runtime=0; pcb.IOTime=Integer.parseInt(GUI.txtfield2.getText()); pcb.WaitIO=Integer.parseInt(GUI.txtfield3.getText()); pcb.rank=GUI.i; // pcb.WaitIO=pcb.IOWait; System.out.println("WaitIO:"+pcb.WaitIO); pcb.Priority=Integer.parseInt(GUI.txtfield4.getText()); String S= pcb.name+"("+GUI.txtfield1.getText()+","+GUI.txtfield2.getText() +","+GUI.txtfield3.getText()+","+GUI.txtfield4.getText()+")"; ReadyQueue.add(pcb); System.out.println(ReadyQueue.size()); JLabel Label=new JLabel(S); Label.setOpaque(true); Label.setBackground(Color.GRAY); GUI.jPanel.add(Label); GUI.jPanel.updateUI(); // GUI.add(GUI.jPanel); System.out.println(S); } } });
-
时间+1按钮监听方法
主要看这个,结合流程图来看,我不想打了,好累😫
//时间+1按钮监听方法 GUI.btn4.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (ReadyQueue.size() == 0 && RunningQueue.size() == 0 && BlockingQueue.size() == 0) JOptionPane.showMessageDialog(null, "请创建进程!!!", "错误 ", 0); else { int tag=0; GUI.time++; GUI.label5.setText(Integer.toString(GUI.time)); GUI.jPanel4_3.updateUI(); if ( ReadyQueue.size() != 0&&RunningQueue.size()==0) { //调度算法 SchedulingAlgorithmPool(GUI,ReadyQueue); System.out.println("更新jPanel组件"); RunningQueue.add(ReadyQueue.get(0)); RunningQueue.get(0).state = "运行"; ReadyQueue.remove(0);//从就绪中移除 //刷新就绪队列 RefreshPanel(GUI,ReadyQueue,0); RunningQueue.get(0).runtime++; RunningQueue.get(0).UsedCPU--; //更新运行进程信息 RefreshPanel(GUI,RunningQueue,1); //打印 Print(GUI,ReadyQueue,RunningQueue,BlockingQueue,FinishQueue); tag=1; } //如果进程队列不为零 if (RunningQueue.size() != 0&&tag==0) { RunningQueue.get(0).runtime++; RunningQueue.get(0).UsedCPU--; //更新运行进程信息 RefreshPanel(GUI,RunningQueue,1); if ((RunningQueue.get(0).CPUTime-RunningQueue.get(0).UsedCPU) == RunningQueue.get(0).IOTime ) { RunningQueue.get(0).state = "阻塞"; BlockingQueue.add(RunningQueue.get(0)); RunningQueue.remove(0);//移除执行队列中的进程 //更新运行进程信息 RefreshPanel(GUI,RunningQueue,1); //更新阻塞队列信息 RefreshPanel(GUI,BlockingQueue,3); // GUI.mutex = 1; GUI.mutex1 = 1; //打印 Print(GUI,ReadyQueue,RunningQueue,BlockingQueue,FinishQueue); } } //如果进程需要CPU时间已用完,则加入到完成队列 if (RunningQueue.size() != 0 && RunningQueue.get(0).UsedCPU < 1) { System.out.println("运行进程:"+RunningQueue.get(0).name+":"+RunningQueue.get(0).UsedCPU); RunningQueue.get(0).state = "完成"; FinishQueue.add(RunningQueue.get(0));//加入到完成队列中 RunningQueue.remove(0);//移除执行队列中的进程 //更新运行进程信息 RefreshPanel(GUI,RunningQueue,1); // GUI.mutex = 1; //打印 Print(GUI,ReadyQueue,RunningQueue,BlockingQueue,FinishQueue); } if (BlockingQueue.size() != 0) { int i,length; if (GUI.mutex1 == 1) { length = BlockingQueue.size() - 1; GUI.mutex1 = 0; } else length = BlockingQueue.size(); for (i=0; i < length; i++) { BlockingQueue.get(i).WaitIO--; BlockingQueue.get(i).runtime++; System.out.println("进程的I/O需求时间:"+BlockingQueue.get(i).WaitIO); //如果阻塞队列中的进程 I/O请求时间已到,则加入到就绪队列中 if (BlockingQueue.get(i).WaitIO <= 0) { BlockingQueue.get(i).state = "就绪"; ReadyQueue.add(BlockingQueue.get(i)); //加入到就绪队列中 BlockingQueue.remove(i); //从阻塞队列中移除 length--;//更新阻塞队列长度 //打印 Print(GUI,ReadyQueue,RunningQueue,BlockingQueue,FinishQueue); } } //更新阻塞队列信息 RefreshPanel(GUI,BlockingQueue,3); //调度算法 SchedulingAlgorithmPool(GUI,ReadyQueue); //更新就绪队列面板 RefreshPanel(GUI,ReadyQueue,0); } } } });
-
-
重置按钮监听方法
//重置按钮监听方法 GUI.btn2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { GUI.jPanel.removeAll(); GUI.jPanel.updateUI(); GUI.jPanel1.removeAll(); GUI.jPanel1.updateUI(); GUI.jPanel3.removeAll(); GUI.jPanel3.updateUI(); GUI.jPanel4_3.updateUI(); GUI.text.setText(""); GUI.jPanel2.updateUI(); GUI.i=0; GUI.time=0; // GUI.mutex=1; GUI.mutex1=1; GUI.label5.setText(Integer.toString(GUI.time)); GUI.type=-1; System.out.println("type:"+GUI.type); ReadyQueue.clear();//清空 BlockingQueue.clear();//清空 FinishQueue.clear();//清空 RunningQueue.clear();//清空 System.out.println("重置"); } });