目标:设计一个有 N个进程共享的进程调度程序。
进程调度算法:
采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。
关于进程:
每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
- 进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
- 进程的到达时间为进程输入的时间。
- 进程的运行时间以时间片为单位进行计算。
- 每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
进程模拟:
- 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
- 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程。
- 如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。
Java代码实现:
-
进程类代码:
public class Pro {
public String name;//进程的名字
public int number;//优先权
public int arr_time;//到达时间
public int CPU_time;//服务 运行时间
public int Need_time;//需要的时间
public char s;//运行状态
//运行时间+1
public void setCPU_time() {
CPU_time=CPU_time+1;
}
//已执行时间
public void setCPU_time(int t) {
CPU_time=t;
}
//修改状态
public void setState(char s) {
this.s=s;
}
@Override
public String toString() {
return "Pro [name=" + name + ", number=" + number + ", arr_time=" + arr_time + ", CPU_time=" + CPU_time
+ ", Need_time=" + Need_time + ", s=" + s + "]";
}
//构造函数
public Pro(String name, int number, int arr_time, int cPU_time, int need_time, char s) {
super();
this.name = name;
this.number = number;
this.arr_time = arr_time;
CPU_time = cPU_time;
Need_time = need_time;
this.s = s;
}
}
-
主函数代码:
public class Main {
public static void main(String[] args) {
Pro [] p=new Pro[4];
//name 优先权number 到达arr_timr 服务CPU_time 需要Need_time 状态s
//s 等待W 运行R 完成F
p[0]=new Pro("A",3,2,0,10,'W');
p[1]=new Pro("B",2,0,0,3,'W');
p[2]=new Pro("C",1,1,0,2,'W');
p[3]=new Pro("D",5,5,0,5,'W');
System.out.println("先来先服务 非抢占式:");
FCFS(p);//先来先服务 非抢占式
System.out.println("先来先服务 抢占式:");
FCFS_preempt(p);//先来先服务 抢占式
}
//先来先服务 抢占式
public static void FCFS_preempt(Pro [] P) {
int c_time=0;//当前时刻
//排序
Pro [] temp=new Pro[1];//临时变量数组
for(int n=0;n<P.length-1;n++) {
for(int m=0;m<P.length-n-1;m++) {
//根据arr_time
if(P[m+1].arr_time<P[m].arr_time) {
temp[0]=P[m];
P[m]=P[m+1];
P[m+1]=temp[0];
}
}
}
//执行
for(int i=0;i<P.length;i++) {
if(c_time>=P[i].arr_time) {
//排序 优先权抢占
for(int n=0;n<i;n++) {
for(int m=0;m<i-n;m++) {
//根据number
if(P[m+1].number<P[m].number) {
temp[0]=P[m];
P[m]=P[m+1];
P[m+1]=temp[0];
}
}
}
/*for(int ch=0;ch<P.length;ch++) {
System.out.print(P[ch].name+" "+P[ch].number+" ");
}
System.out.println("c_time"+c_time);*/
if(i!=0) {
P[i-1].setState('W');}//阻塞
if(P[i].Need_time!=P[i].CPU_time) {
P[i].setState('R');//设置运行状态
P[i].setCPU_time();//执行进度+1
if(P[i].Need_time==P[i].CPU_time) {
P[i].setState('F');//完成状态
//输出
System.out.println("已完成:"+P[i].name+",完成时刻:"+c_time);
}
}
c_time++;//时间进度+1
//全部进程到达 按优先权执行
if(i==(P.length-1)) {
for(int e=i;e>=0;e--) {
if(P[e].Need_time!=P[e].CPU_time) {
P[e].setState('R');//设置运行状态
c_time=c_time+(P[e].Need_time-P[e].CPU_time);//时间进度+剩余进程时间
//System.out.println(P[e].name+"cpu已执行"+P[e].CPU_time);
P[e].setCPU_time(P[e].Need_time);//执行时间加满
if(P[e].Need_time==P[e].CPU_time) {
P[e].setState('F');//完成状态
}
//输出
System.out.println("已完成:"+P[e].name+",完成时刻:"+c_time);
}
}
}
}
else {
i--;//重新进行本次循环
P[i].setCPU_time();//执行进度+1
if(P[i].Need_time==P[i].CPU_time) {
P[i].setState('F');//完成状态
//输出
System.out.println("已完成:"+P[i].name+",完成时刻:"+c_time);
}
c_time++;//时间进度+1
}
}
}
//先来先服务 非抢占式
public static void FCFS(Pro [] P) {
int c_time=0;//当前时刻
//排序
Pro [] temp=new Pro[1];//临时变量数组
for(int n=0;n<P.length-1;n++) {
for(int m=0;m<P.length-n-1;m++) {
//根据arr_time 先来先服务 非抢占式
if(P[m+1].arr_time<P[m].arr_time) {
temp[0]=P[m];
P[m]=P[m+1];
P[m+1]=temp[0];
}
}
}
//执行
for(int i=0;i<P.length;i++) {
if(c_time>=P[i].arr_time) {
P[i].setState('R');//设置运行状态
P[i].setCPU_time(P[i].Need_time);//执行时间
if(P[i].Need_time==P[i].CPU_time) {
P[i].setState('F');//完成状态
}
c_time=c_time+P[i].Need_time;//时间进度+进程时间
//输出
System.out.println("已完成:"+P[i].name+",完成时刻:"+c_time);
}
else {
c_time++;//时间进度+1
i--;//重新进行本次循环
}
}
}
}