操作系统处理器调度模拟实操
一、实验内容:
选择一个调度算法,实现处理器调度。
二、实验目的:
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实习模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。
- 实验题目:
设计一个按优先数调度算法实现处理器调度的程序。
[提示]:
(1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名 |
指针 |
要求运行时间 |
优先数 |
状态 |
其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。
指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。
要求运行时间——假设进程需要运行的单位时间数。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。
(2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。
(3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。例:
队首标志
K2
K1 |
P1 |
K2 |
P2 |
K3 |
P3 |
K4 |
P4 |
K5 |
P5 |
|
0 |
|
K4 |
|
K5 |
|
K3 |
|
K1 |
|
2 |
|
3 |
|
1 |
|
2 |
|
4 |
|
1 |
|
5 |
|
3 |
|
4 |
|
2 |
|
R |
|
R |
|
R |
|
R |
|
R |
|
PCB1 |
|
PCB2 |
|
PCB3 |
|
PCB4 |
|
PCB5 |
(4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实习是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:
优先数-1
要求运行时间-1
来模拟进程的一次运行。
提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。
(5) 进程运行一次后,若要求运行时间¹0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。
(6) 若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。
(7) 在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进程队列的变化。
(8) 为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
四、核心代码及注释:
PCB实体类:定义PCB的属性,生成set和get方法
import java.util.Random;
public class ProcessPCB {
private String processName; //进程名
private Integer runTime; //运行时间
private Integer priorityLevel; //优先级
private Character status; //状态 R代表就绪 E代表结束
public ProcessPCB(String processName) {
Random random = new Random();
this.priorityLevel = random.nextInt(10) + 1; //优先级的范围随机为1-10
this.runTime = random.nextInt(10) + 1; //运行时间的范围随机为1-10
this.processName = processName;
this.status = 'R';//初始值为R
}
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
public Integer getRunTime() {
return runTime;
}
public void setRunTime(Integer runTime) {
this.runTime = runTime;
}
public Integer getPriorityLevel() {
return priorityLevel;
}
public void setPriorityLevel(Integer priorityLevel) {
this.priorityLevel = priorityLevel;
}
public Character getStatus() {
return status;
}
public void setStatus(Character status) {
this.status = status;
}
public void Start() {
this.priorityLevel = priorityLevel - 1; //每运行一次,优先级-1
this.runTime = runTime - 1;//每运行一次,运行时间-1
}
public void Ending() {
this.status = 'E'; //调用Ending方法后,状态全部设置为E
}
@Override
public String toString() { //重写ToString方法,返回进程信息
return "PCB" + processName.substring(1) + "{" +
"Name='" + processName + '\'' +
", runTime=" + runTime +
", priorityLevel=" + priorityLevel +
", Status=" + status +
'}';
}
}
PCB功能实现类,进行处理器调度算法的模拟
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class ProcessDemo {
//该接口代表一个比较器,比较两个对象谁排在前谁排在后
static class CompareTime implements Comparator<ProcessPCB>{
@Override
public int compare(ProcessPCB p1, ProcessPCB p2) {
if(p1.getPriorityLevel()==p2.getPriorityLevel()){
return (p2.getRunTime().compareTo(p1.getRunTime()))*-1;
}else{
return p2.getPriorityLevel().compareTo(p1.getPriorityLevel());
}
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList<ProcessPCB> pointerR = new ArrayList<ProcessPCB>();
ArrayList<ProcessPCB> pointerE = new ArrayList<ProcessPCB>();
System.out.println("请输入线程名,中间请用空格隔开");
String threadName = scan.nextLine();
String[] s = threadName.split(" ");
for (int i = 0; i < s.length; i++) {
pointerR.add(new ProcessPCB(s[i]));
}
CompareTime cT = new CompareTime();
int count = 0;//进程运行次数
System.out.println("--------运行之前:---------");
for (ProcessPCB p:pointerR) {
System.out.println(p.toString());
}
System.out.println();
System.out.println("-----------开始运行------------");
while (pointerR.size() != 0){
count++;
for (int j = 0; j < pointerR.size()+1; j++) {
Collections.sort(pointerR, cT);
//Collections是一个工具类,sort是其中的静态方法,是用来对List类型进行排序的
}
ProcessPCB pFirtst = pointerR.get(0);
//选择优先级高的进程进行运行
System.out.println("第" + count + "次被选中的进程名为:" + pFirtst.getProcessName());
for (ProcessPCB p:pointerR) {
System.out.println(p.toString());
}
pointerR.get(0).Start();
if (pointerR.get(0).getRunTime() != 0) {
//运行一次后,若要求运行时间不等于零,则再将它加入到队列中(按优先数大小插入)
}else {
//要求运行时间等于零,则修改状态为“E”,且退出队列
pointerR.get(0).Ending();
System.out.println("线程"+pointerR.get(0).getProcessName()+"已退出,请选择是插入新进程或继续运行:(输入新线程名或输入1继续)");
pointerR.remove(0);
String strName = scan.next();
if (!("1".equals(strName))){
pointerR.add(new ProcessPCB(strName));
}
pointerE.add(pFirtst);
}
}
System.out.println();
System.out.println("----------所有进程运行结束---------");
System.out.println("所有进程状态如下:");
for (ProcessPCB p:pointerE) {
System.out.println(p.toString());
}
}
}
- 打印效果图:
输入线程名字,随机生成运行时间和优先级,初始状态都为R就绪态
当一个线程结束后,会提示是否插入新线程或者继续执行
所有线程结束后,运行时间清零,状态置为E(结束)
六、实验总结:
本次实验通过课本处理器调度的进程的初步认识和实验按优先数调度算法实现处理器调度的实现,了解到进程与进程控制块之间的联系,进程运行过程中状态以及已运行时间的判断和计算,选中运行的进程名以及选中进程运行后的各进程控制块状态。
好了,关于此次操作系统的处理器调度就说到这里了,如有不足之处,欢迎指正!
感恩能与大家在华为云遇见!希望能与大家一起在华为云社区共同成长。
- 点赞
- 收藏
- 关注作者
评论(0)