【實驗目的】
- 掌握進程控制塊的作用和實現技術;
- 熟悉操作系統的進程調度算法及實現方法。
【實驗原理】
每個進程有一個進程控制塊(PCB)表示。進程控制塊可以包含如下信息:進程名、優先數、到達時間、需要運行時間、已用CPU時間、進程狀態等等。
進程的優先數及需要的運行時間可以事先人爲地指定(也可以由隨機數產生)。進程的到達時間爲進程輸入的時間。
進程的運行時間以時間片爲單位進行計算。
每個進程的狀態可以是就緒 W(Wait)、運行R(Run)、或完成F(Finish)三種狀態之一。
就緒進程獲得 CPU後都只能運行一個時間片。用已佔用CPU時間加1來表示。
如果運行一個時間片後,進程的已佔用 CPU時間已達到所需要的運行時間,則撤消該進程,如果運行一個時間片後進程的已佔用CPU時間還未達所需要的運行時間,也就是進程還需要繼續運行,此時應將進程的優先數減1(即降低一級),然後把它插入就緒隊列等待CPU。
每進行一次調度程序都打印一次運行進程、就緒隊列、以及各個進程的 PCB,以便進行檢查。
重複以上過程,直到所要進程都完成爲止。
【代碼(Java實現)】
首先是一個輔助類:
public class Shuru {
String name;
int Super;
int zxTime;
int ddtime;//到達時間
int runtime;//剩餘執行時間
String zt;//進程狀態
}
正式代碼:
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];
int zzxtime = 0;// 總執行時間
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].zxTime = sr[i].nextInt();
System.out.print("請輸入到達時間:");
shuru[i].ddtime=sr[i].nextInt();
zzxtime += shuru[i].zxTime;
shuru[i].runtime = shuru[i].zxTime;
}
System.out.println("***************************************");
for (int i = 0; i < zzxtime; i++) {
System.out.println("*******************************這是第"+(i+1)+"次執行*****"
+ "***************************************");
sort(shuru);// 將優先級進行排序
shuru[n - 1].Super -= 1;// 優先級減一
shuru[n - 1].runtime = shuru[n - 1].runtime - 1;// 剩餘執行次數減一
System.out.println("現在正在執行的進程是:" + shuru[n - 1].name);
System.out.println("進程名\t 優先級 \t 剩餘執行時間 \t狀態");
shuru[n-1].zt="r";
show(shuru[n - 1]);
System.out.println("就緒中的進程有:");
System.out.println("進程名\t 優先級 \t 剩餘執行時間\t狀態");
for (int j = 0; j < n - 1; j++) {
if (shuru[j].runtime != 0 && shuru[j].Super != 0) {
for (int k = j; k < n - 1; k++) {
shuru[k].zt="w";
show(shuru[k]);
break;
}
}
}
if (shuru[n - 1].runtime == 0) {// 如果剩餘執行次數爲0,進程結束
System.out.println("__________進程" + shuru[n - 1].name + "結束_____________");
shuru[n - 1].Super = 0;// 如果一個進程執行完畢,將它的優先級置零
}
}
}
public void sort(Shuru shuru[]) {// 比較優先級
for (int i = 1; i <= shuru.length; i++) {// 計數,第幾輪比較
for (int j = 0; j < shuru.length - i; j++) {// 注意這一步,第一趟比較length次,第二趟比較length-1次,以此類推
if (shuru[j].Super > shuru[j + 1].Super) {
Shuru t = shuru[j];
shuru[j] = shuru[j + 1];
shuru[j + 1] = t;// 交換
}
}
}
}
public void sort1(Shuru shuru[]) {//比較到達時間
for (int i = 1; i <= shuru.length; i++) {// 計數,第幾輪比較
for (int j = 0; j<shuru.length - i; j++) {// 注意這一步,第一趟比較length次,第二趟比較length-1次,以此類推
if (shuru[j].ddtime >shuru[j + 1].ddtime) {
Shuru t = shuru[j];
shuru[j] = shuru[j + 1];
shuru[j + 1] = t;// 交換
}
}
}
}
public void begin2(int n) {
Scanner sr[] = new Scanner[n];
Shuru shuru[] = new Shuru[n];
int yxj[] = new int[n];
int zzxtime = 0;// 總執行時間
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].zxTime = sr[i].nextInt();
System.out.print("請輸入到達時間:");
shuru[i].ddtime=sr[i].nextInt();
zzxtime += shuru[i].zxTime;
shuru[i].runtime = shuru[i].zxTime;
}
int count=0;
for(int i=0;i<zzxtime;i++) {
System.out.println("*******************************"
+ "**這是第"+(i+1)+"次執行**************************************");
shuru[count].runtime = shuru[count].runtime - 1;// 剩餘執行次數減一
sort1(shuru);
System.out.println("現在正在執行的進程是:" + shuru[count].name);
System.out.println("進程名\t 剩餘執行時間\t 到達時間\t\t狀態");
shuru[count].zt="r";
show1(shuru[count]);
System.out.println("就緒中的進程有:");
System.out.println("進程名\t 剩餘執行時間 \t到達時間\t\t狀態");
for(int j=count+1;j<n;j++) {
shuru[j].zt="w";
show1(shuru[j]);
}
if (shuru[count].runtime == 0) {// 如果剩餘執行次數爲0,進程結束
System.out.println("__________進程" + shuru[count].name + "結束_____________");
count++;
}
}
}
public void show(Shuru shuru) {
System.out.println(shuru.name + "\t" + shuru.Super + "\t " + shuru.runtime+"\t\t"+shuru.zt);
}
public void show1(Shuru shuru) {
System.out.println(shuru.name + "\t" + shuru.runtime+"\t\t"+shuru.ddtime+"\t\t"+shuru.zt);
}
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);
}else if(choice==2) {
j.begin2(n);
}
else {
System.out.println("輸入錯誤!請重新輸入!");
}
System.out.println("所有進程執行完畢!");
}
}
【結果截圖】
還可以選擇先來先服務:
轉載請註明出處~我是一個有夢想的baby girl!