先来先服务算法是一种最简单的算法,可用于进程调度,也可用于作业调度。
如名,进程调度采用FCFS算法时,每次调度都是从就绪队列中选取一个最先进入队列的进程,分配处理及,该进程一直运行到完成或者发生事件而阻塞才放弃处理机
该算法比较利于长作业(进程),不利于短作业;原因:短作业等待时间过长
该算法有利于CPU繁忙型(指需要大量cpu时间)的作业,不利于I/O繁忙型
短作业优先调度算法是指对短作业或短进程优先调度的算法,从就绪队列中找到预计最短运行时间的进程,让处理机调度它
优点:可以有效降低作业的平均等待时间,提高系统吞吐量。
缺点:对长作业不利,周转时间与带权周转时间提升。未考虑作业的紧迫程度。时间长短是估计的,所以不一定会达到真正的短作业调度
类同于短作业优先调度算法
利用FCFS再令其执行一个时间片,时间片用完时,发生中断,将其送入就绪队列尾部
既能使高优先级的作业得到响应又能使短作业(进程)迅速完成
public class PCB {
private String name;
private int id;
private int priority;
private int arrive_time;
private int demandrun_time;
private int user_time;
private Status status;
public static int run_time=0;
public PCB(){
user_time = 0;
status = Status.H;
}
public PCB(String name,int id,int priority,int demandrun_time){
this();
this.name = name;
this.id = id;
this.priority = priority;
this.demandrun_time = demandrun_time;
}
public boolean isFinish(PCB pcb){
if(pcb.getDemandrun_time() == pcb.getUser_time()){
return true;
}
return false;
}
public void run(int time){
if((user_time+time) < demandrun_time){
user_time +=time;
run_time+=time;
}else{
run_time = run_time + demandrun_time - user_time;
user_time = demandrun_time;
status = Status.F;
}
}
public double hrr_priority(){
return (double)(run_time-user_time+demandrun_time)/demandrun_time;
}
...
@Override
public String toString() {
return "进程状态:"+status+" 进程名:"+name +" 进程ID:"+ id +" 进程需求运行时间:"+ demandrun_time +" 优先级:"+priority+" 进程运行时间:"+ user_time;
}
public enum Status{
H,W,R,F;
}
}
List<PCB> pcbs = new ArrayList<>(Arrays.asList(
new PCB("A",1,10,100),
new PCB("B",2,9,105),
new PCB("C",3,54,120),
new PCB("D",4,24,210),
new PCB("E",5,14,200)
));
如果存在任何进程在就绪状态(W)或者执行状态(R)则调度未完成
public boolean isFinish(List<PCB> pcbs){
boolean flag = pcbs.stream()
.anyMatch((e)->e.getStatus().equals(Status.W));
boolean flag1 = pcbs.stream()
.anyMatch((e)->e.getStatus().equals(Status.R));
// Long count1 = pcbs.stream().filter((e)->e.getStatus().equals(Status.W)).collect(Collectors.counting());
// Long count2 = pcbs.stream().filter((e)->e.getStatus().equals(Status.R)).collect(Collectors.counting());
if(!flag&&!flag1){
return true;
}
return false;
}
public void fcfs(List<PCB> pcbs){
while(!isFinish(pcbs)){
//找到队列中第一个状态处于就绪状态的进程
Optional<PCB> op = pcbs.stream()
.filter((e)->e.getStatus().equals(Status.W))
.findFirst();
//把进程状态改为执行状态
op.get().setStatus(Status.R);
//进程一直运行到完成
while(!op.get().isFinish(op.get())){
op.get().run(10);
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("CPU运行时间:"+PCB.run_time);
show(Status.F);
show(Status.R);
show(Status.W);
show(Status.H);
System.out.println();
}
}
}
public void sjf(List<PCB> pcbs){
//按进程可能用到的时长排序,由小到大
List<PCB> sortpcbs = pcbs.stream().sorted((e1,e2)->e1.getDemandrun_time()-e2.getDemandrun_time()).collect(Collectors.toList());
//排序后和先来先服务算法类似
fcfs(sortpcbs);
}
public void pt(List<PCB> pcbs){
//按进程优先权排序
List<PCB> sortpcbs = pcbs.stream().sorted((e1,e2)->e1.getPriority()-e2.getPriority()).collect(Collectors.toList());
fcfs(sortpcbs);
}
public void tsc(List<PCB> pcbs){
while(!isFinish(pcbs)){
//获取所有进程数
Long count = pcbs.stream().filter((e)->e.getStatus().equals(Status.W)).collect(Collectors.counting());
for(int i = 0;i<count;i++){
//获取应调度的进程
Optional<PCB> op = pcbs.stream()
.filter((e)->e.getStatus().equals(Status.W))
.skip(i)
.findFirst();
op.get().setStatus(Status.R);
op.get().run(10);
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("CPU运行时间:"+PCB.run_time);
show(Status.F);
show(Status.R);
show(Status.W);
show(Status.H);
System.out.println();
//时间片完后把执行状态转换为就绪状态
if(op.get().getStatus().equals(Status.R)){
op.get().setStatus(Status.W);
}else{
count --;
}
}
}
}
public void hrr(List<PCB> pcbs){
while(!isFinish(pcbs)){
//获取当前相对优先级最高的进程
Optional<PCB> op = pcbs.stream()
.filter((e)->e.getStatus().equals(Status.W))
.max((e1,e2)->Double.compare(e1.hrr_priority(), e2.hrr_priority()));
op.get().setStatus(Status.R);
op.get().run(10);
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("CPU运行时间:"+PCB.run_time);
show(Status.F);
show(Status.R);
show(Status.W);
show(Status.H);
System.out.println();
if(op.get().getStatus().equals(Status.R)){
op.get().setStatus(Status.W);
}
}
}