操作系统SPF算法Java实现

前几天上课操作系统实验课课用java做了实现一下SPF短进程优先调度算法,代码水平很低,适合新手理解,在这里分享一下我的代码,希望能帮助到同学们,(彭彩虹老师的操作系统实验课速进)

算法描述

 进程类

class ProcessData {
	//作业号
	public int id;
    // 到达时间
    public int arriveTime;
    // 服务时间
    public int serviceTime;
    //开始时间
    public int runtime;
    // 完成时间
    public int finishTime;
    // 周转时间
    public int turnTime;
    // 带权周转时间
    public double powerTime;
    //判断是否处理过
    public boolean finish=false;

	// 作业的构造方法中传来的初值为到达时间和服务时间
    public ProcessData(int id,int arriveTime, int serviceTime) {
    	this.id=id;
        this.arriveTime = arriveTime;
        this.serviceTime = serviceTime;
    }

	// 重写toString方法便于之后的数据展示
    @Override
    public String toString() {
        return  id + "\t" +
        		arriveTime + "\t" +
                serviceTime + "\t" + 
                runtime + "\t" +
                finishTime + "\t" + 
                turnTime + "\t" + 
                powerTime;
    }
    public String qString() {
    	return  id + "\t" +
        		arriveTime + "\t" +
                serviceTime + "\t" ;
    }
}

运行主类

主要的算法思想是,设置一个从零到所有作业结束的时间节点,循环每个时间点,判断当前时间系统是否空闲且是否有作业到达,有作业到达则将到达的作业根据服务时间排好序,设置相应的系统释放时间即下一个系统空闲时间,在下一个系统空闲时间重复该步骤。

代码很长,但注释尽可能详细了


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ProcessProject {
    // 平均周转时间
    public static double avgTotalTime;
    // 平均带权周转时间
    public static double avgPowerTime;

    public static void main(String[] args) {
    	// 定义长度为4,类型为作业数据类的作业数组用于存储4个作业
        ProcessData[] processData = new ProcessData[4];
        // 定义三个个作业作业号,到达时间,服务时间
        processData[0] = new ProcessData(1,0,2);
        processData[1] = new ProcessData(2,1,3);
        processData[2] = new ProcessData(3,2,1);
        processData[3] = new ProcessData(4,4,3);
        
        // 调用SPF算法
        SPF(processData);
    }

    //SPF算法方法
    private static void SPF(ProcessData[] processData) {
    	int preFinished = 0; // 前一个作业的完成时间即为下一个作业的开始时间
    	int nextrelease=0;//下一次的释放时间
    	int end=0;//运行总时间
    	boolean isrelease=false;//判断系统当前是否释放即判断能否运行作业
        avgTotalTime = 0;    // 平均周转时间  
        avgPowerTime = 0;  // 平均带权周转时间
        ProcessData p;//用于队列位置交换的对象

        // 初始化完成时间、周转时间、带权周转时间的初值为0
        for (int i = 0; i < processData.length; i++) {
            processData[i].finishTime = 0; // 设置初始完成时间为0
            processData[i].turnTime = 0; // 设置初始周转时间为0
            processData[i].powerTime = 0; // 设置初始带权周转时间为0
        }
        
        //初始化结束时间
        for(int i=0;i<processData.length;i++) {
        	end=end+processData[i].serviceTime;
        }
        //一下两个list用于临时排序
        List<ProcessData> list=new ArrayList<ProcessData>();
        List<ProcessData> temp=new ArrayList<ProcessData>();
        //SPF排序算法
        for(int time=0;time<=end;time++) {//time为时间
        	//判断当前是否释放
        	if(time==0||time>=nextrelease) {
        		isrelease=true;
        	}
        	//如果释放了则跳到下个时间节点
        	if (!isrelease) {
				continue;
			}
        	//将队列中的作业在该时间下已经到达的作业加入到临时队列
        	for(int i=0;i<processData.length;i++) {
        		if(processData[i].arriveTime<=time&&!processData[i].finish) {
        			temp.add(processData[i]);
        		}
        	}
        	//同一时间下根据服务时间排序
        	if(temp.size()==0) {
				continue;
        	}if (temp.size()==1) {
				//用于跳过服务时间排序
			}else {
        		for(int j=0;j<temp.size()-1;j++) {
    	        	for(int k=0;k<temp.size()-1;k++) {
    	            	if(temp.get(k).serviceTime>temp.get(k+1).serviceTime) {
    	            		p=temp.get(k);
    	            		temp.set(k, temp.get(k+1));
    	            		temp.set(k+1, p);
    	            	}
    	            }
    	        }
			}
        	//将临时队列中的最服务时间最短的作业处理
			if(temp.size()>0) {
				temp.get(0).finish=true;//将作业的finsh属性设置为true,代表该作业已经被处理,下一个时间节点将不会考虑
				nextrelease=nextrelease+temp.get(0).serviceTime;//设置下一次系统空闲的时间节点
				list.add(temp.get(0));
				
			}
			if (time<nextrelease) {//决定系统是否释放
				isrelease=false;
			}
			temp=new ArrayList<ProcessData>();//清空temp,用于下一个时间节点
        }
       //将作业处理顺序重新存入processDa[]队列中
        for(int i=0;i<list.size();i++) {
        	processData[i]=list.get(i);
        }
        // 如果第一个作业的到达时间不等于前一个作业的完成时间,就将前一个作业的完成时间定义为当前作业的到达时间
        if (processData[0].arriveTime != preFinished) {
            preFinished = processData[0].arriveTime;
        }

        for (int i = 0; i < processData.length; i++) {
        	//开始时间计算
        	if(preFinished<processData[i].arriveTime) {//当前一个作业已完成,而且第二个作业未到时
        		processData[i].runtime=processData[i].arriveTime;
        		preFinished=processData[i].arriveTime;
        	}else {//否则该作业的开始时间为上一个作业的完成时间
        		processData[i].runtime=preFinished;
        	}
        	
        	// 作业的完成时间为上一个作业的完成时间加当前作业的服务时间
            processData[i].finishTime = preFinished + processData[i].serviceTime;
            preFinished = processData[i].finishTime;
            // 周转时间 = 完成时间 - 到达时间
            processData[i].turnTime = processData[i].finishTime - processData[i].arriveTime;
            // 带权周转时间 = 作业的周转时间 / 系统提供服务的时间
            processData[i].powerTime = (double) processData[i].turnTime / (double) processData[i].serviceTime;
        }

        System.out.println("SPF算法:");

        // 打印进程的信息
        Display(processData);
    }

    private static void Display(ProcessData[] processData) {
        System.out.println("进程号\t" +"到达时间\t" + "运行时间\t" + "开始时间\t"+ "结束时间\t" + "周转时间\t" + "带权周转时间\t");
        for (int i = 0; i < processData.length; i++) {
            System.out.println(processData[i]);
            avgTotalTime += processData[i].turnTime; // 求总周转时间,此时avgTotalTime中存储的值为总周转时间
            avgPowerTime += processData[i].powerTime; // 求总带权周转时间,此时avgPowerTime中存储的值为总带权周转时间
        }

        avgTotalTime = avgTotalTime / processData.length; // 平均周转时间
        avgPowerTime = avgPowerTime / processData.length; // 平均带权周转时间

        System.out.println("平均周转时间:" + avgTotalTime);
        System.out.println("平均带权周转时间:" + avgPowerTime);
    }
}

效果图

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
Python本身并不是操作系统,因此不能直接进行进程调度。但是,Python提供了一些模块可以用于操作系统编程,如`os`、`subprocess`等模块。如果你想了解操作系统进程调度算法SPF的Python实现,可以参考以下代码: ```python import heapq class Process: def __init__(self, pid, arrival_time, burst_time): self.pid = pid self.arrival_time = arrival_time self.burst_time = burst_time self.remaining_time = burst_time def __lt__(self, other): return self.remaining_time < other.remaining_time def execute(self, time): if self.remaining_time > time: self.remaining_time -= time return False else: return True def spf(processes): n = len(processes) processes.sort(key=lambda p: p.arrival_time) ready_queue = [] current_time = 0 completed_processes = [] i = 0 while i < n or ready_queue: while i < n and processes[i].arrival_time <= current_time: heapq.heappush(ready_queue, processes[i]) i += 1 if not ready_queue: current_time = processes[i].arrival_time continue p = heapq.heappop(ready_queue) if p.execute(1): p.completion_time = current_time + 1 completed_processes.append(p) else: heapq.heappush(ready_queue, p) current_time += 1 return completed_processes # Example usage processes = [ Process(1, 0, 5), Process(2, 1, 3), Process(3, 2, 8), Process(4, 3, 6), Process(5, 4, 2) ] completed_processes = spf(processes) for p in completed_processes: print(f"Process {p.pid} completed at time {p.completion_time}") ``` 这段代码实现SPF(Shortest Process First)算法,它按照进程的剩余执行时间来进行调度。在这个实现中,`Process`类表示一个进程,`spf`函数接受一个进程列表并返回已完成的进程列表。在`spf`函数中,我们首先按照到达时间对进程进行排序,然后使用一个堆作为就绪队列,每次选择剩余执行时间最短的进程执行。如果有多个进程剩余执行时间相同,则选择先到达的进程。在每个时间片结束时,如果进程已经执行完毕,则将其加入已完成列表,否则将其重新加入就绪队列。最后,返回已完成的进程列表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邻家小妹妹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值