【实验目的】
- 掌握进程控制块的作用和实现技术;
- 熟悉操作系统的进程调度算法及实现方法。
【实验原理】
每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
【代码(Java实现)】
首先是一个辅助类:
public class Shuru {
String name;//进程名
int Super;//优先级
double ddtime;//到达时间
double yxtime;//运行时间
double kstime;//开始时间
double jstime;//结束时间
double zztime;//周转时间
double dqzztime;//带权周转时间
}
正式代码:
import java.text.BreakIterator; import java.util.Scanner; public class Jincheng { Scanner s = new Scanner(System.in); public void begin1(int n) { Scanner sr[] = new Scanner[n]; Shuru shuru[] = new Shuru[n]; int yxj[] = new int[n]; for (int i = 0; i < n; i++) { System.out.println("进程" + (i + 1) + "信息输入:"); shuru[i] = new Shuru(); sr[i] = new Scanner(System.in); System.out.print("请输入进程名:"); shuru[i].name = sr[i].nextLine(); System.out.print("请输入优先级:"); shuru[i].Super = sr[i].nextInt(); yxj[i] = shuru[i].Super;// 每次将优先级传给数组 System.out.print("请输入到达时间:"); shuru[i].ddtime=sr[i].nextInt(); System.out.print("请输入运行时间: "); shuru[i].yxtime = sr[i].nextInt(); } sort(shuru);// 将优先级进行排序 for (int i = 0; i < shuru.length; i++) { if(i==0) { shuru[i].kstime=shuru[i].ddtime; } else { if(shuru[i].ddtime<=shuru[i-1].jstime) { shuru[i].kstime=shuru[i-1].jstime; } else { shuru[i].kstime = shuru[i].ddtime; } } shuru[i].jstime=shuru[i].kstime+shuru[i].yxtime; shuru[i].zztime=shuru[i].jstime-shuru[i].ddtime; shuru[i].dqzztime=shuru[i].zztime/shuru[i].yxtime; System.out.println("现在正在执行的进程是:" + shuru[0].name); System.out.println("**************************************************************"); show(shuru[i]); System.out.println("**************************************************************"); } } public void sort(Shuru shuru[]) {// 比较优先级 for (int i = 0; i < shuru.length; i++) {// 计数,第几轮比较 for (int j = i+1; j < shuru.length; j++) {// 注意这一步,第一趟比较length次,第二趟比较length-1次,以此类推 if (shuru[i].Super < shuru[j].Super) { Shuru t = shuru[i]; shuru[i] = shuru[j]; shuru[j] = t;// 交换 } } } } public void sort1(Shuru shuru[]) {//比较到达时间 for (int i = 0; i < shuru.length; i++) {// 计数,第几轮比较 for (int j = i+1; j<shuru.length; j++) {// 注意这一步,第一趟比较length次,第二趟比较length-1次,以此类推 if (shuru[i].ddtime > shuru[j].ddtime) { Shuru t = shuru[i]; shuru[i] = shuru[j]; shuru[j] = t;// 交换 } } } } public void begin2(int n) { Scanner sr[] = new Scanner[n]; Shuru shuru[] = new Shuru[n]; for (int i = 0; i < n; i++) { System.out.println("进程" + (i + 1) + "信息输入:"); shuru[i] = new Shuru(); sr[i] = new Scanner(System.in); System.out.print("请输入进程名:"); shuru[i].name = sr[i].nextLine(); System.out.print("请输入到达时间:"); shuru[i].ddtime=sr[i].nextInt(); System.out.print("请输入运行时间: "); shuru[i].yxtime = sr[i].nextInt(); } sort1(shuru); for(int i=0;i<shuru.length;i++) { if(i==0) { shuru[i].kstime=shuru[i].ddtime; } else { if(shuru[i].ddtime<=shuru[i-1].jstime) { shuru[i].kstime=shuru[i-1].jstime; } else { shuru[i].kstime = shuru[i].ddtime; } } shuru[i].jstime=shuru[i].kstime+shuru[i].yxtime; shuru[i].zztime=shuru[i].jstime-shuru[i].ddtime; shuru[i].dqzztime=shuru[i].zztime/shuru[i].yxtime; System.out.println("现在正在执行的进程是:" + shuru[i].name); System.out.println("**************************************************************"); show1(shuru[i]); System.out.println("**************************************************************"); } } public void show(Shuru shuru) { System.out.println("进程名 优先级 到达时间 运行时间 开始时间 结束时间 周转时间 带权周转时间"); System.out.println(shuru.name + "\t\t" + shuru.Super +"\t\t"+ shuru.ddtime+"\t\t"+shuru.yxtime+"\t\t"+shuru.kstime+"\t\t"+shuru.jstime+"\t\t"+shuru.zztime+"\t\t"+shuru.dqzztime); } public void show1(Shuru shuru) { System.out.println("进程名 到达时间 运行时间 开始时间 结束时间 周转时间 带权周转时间"); System.out.println(shuru.name + "\t\t" + shuru.ddtime+"\t\t"+shuru.yxtime+"\t\t"+shuru.kstime+"\t\t"+shuru.jstime+"\t\t"+shuru.zztime+"\t\t"+shuru.dqzztime); } public static void main(String[] args) { Jincheng j = new Jincheng(); Scanner s1 = new Scanner(System.in); System.out.print("请输入进程数目:"); int n = s1.nextInt(); System.out.println("请输入你要选择的调度算法:(1 最高优先数优先;2 先来先服务)"); int choice=s1.nextInt(); if(choice==1) { j.begin1(n); System.out.println("你还想体验先来先服务算法嘛?请选择:(1 不想;2 先来先服务)"); Scanner s2=new Scanner(System.in); int m1= s2.nextInt(); if(m1==1) { System.out.println("所有进程执行完毕!"); } else if (m1==2) { j.begin2(n); System.out.println("所有进程执行完毕!"); } }else if(choice==2) { j.begin2(n); System.out.println("你还想体验先来先服务算法嘛?请选择:(1 最高优先数优先;2 不想)"); Scanner s3=new Scanner(System.in); int m2= s3.nextInt(); if(m2==2) { System.out.println("所有进程执行完毕!"); } else if (m2==1) { j.begin1(n); System.out.println("所有进程执行完毕!"); } } else { System.out.println("输入错误!请重新输入!"); } } }
【结果截图】