計算機實驗

實驗報告

實驗目的:

就緒進程數大於處理機數時,按照某種策略決定哪些進程優先佔用處理機。實驗模擬處理機調度,加深對處理機調度的理解。

實驗內容:

實驗一模擬短進程優先調度
進程8 個,到達時間和服務時間(用戶輸入)
至少兩種結果: 1 到達時間:0,1,2,….
2 到達時間:其他

實驗源代碼

//進程類
public class Process {
    String processName;     //進程名稱

    int arrivalTime;        //到達時間
    int starTime;           //開始時間
    int finishTime;         //實際完成時間
    int wholeTime;          //運行所需要的的時間;
    public String getProcessName() {
        return processName;
    }
    public int getStarTime() {
        return starTime;
    }

    public int getFinishTime() {
        return finishTime;
    }
    public int getArrivalTime() {
        return arrivalTime;
    }
    public void setFinishTime(int finishTime) {
        this.finishTime = finishTime;
    }
    public void setStarTime(int starTime) {
        this.starTime = starTime;
    }
    public int getWholeTime() {
        return wholeTime;
    }

    public Process(String processName, int arrivalTime, int wholeTime) {
        this.processName = processName;
        this.arrivalTime = arrivalTime;
        this.wholeTime = wholeTime;
    }


}
public class Short_process {
    public static void main(String[] args) {
        ArrayList<Process> arrayList = new ArrayList<>();
        Scanner in = new Scanner(System.in);
        System.out.println("請輸入有幾個進程呢?");
        int numberofprocess = in.nextInt();

        for (int i = 0 ; i<numberofprocess;i++)
        {
            System.out.println("請輸入進程"+(i+1)+"的進程名稱");
            String name = in.next();
            System.out.println("請輸入進程"+(i+1)+"的到達時間");
            int arrivalTime = in.nextInt();
            System.out.println("請輸入進程"+(i+1)+"的運行所需時間");
            int wholeTime = in.nextInt();
            Process process = new Process(name,arrivalTime,wholeTime);
            arrayList.add(process);
            //System.out.println("----------------------------");
        }

        test(arrayList);
    }


    public static void test (ArrayList<Process> arrayList)
    {
        int nowtime =0;                     //當前時間
        int currentprocess=0;               //當前進程
        int remain = arrayList.size();      //剩餘進程數
        int numofprocess =arrayList.size();
        ArrayList<Process> arrayList1 = new ArrayList<>();
        /*
        以到達時間給進程排序;
         */
        Collections.sort(arrayList, new Comparator<Process>() {
            @Override
            public int compare(Process o1, Process o2) {
                return o1.getArrivalTime()<o2.getArrivalTime()?-1:1;
            }
        });
        while (remain>0)
        {

            System.out.println(remain);
            int shortTestArrival = arrayList.get(0).getArrivalTime();
            if (nowtime<shortTestArrival)                               //當前時間沒有進程排隊
                nowtime = shortTestArrival;
            int i = 1;
            currentprocess = 0;
            /*
            尋找到達中的最短進程
             */
            while (arrayList.size()>i &&arrayList.get(i).getArrivalTime()<=nowtime)
            {
                /*

                 */
                if (arrayList.get(i).getWholeTime()<arrayList.get(currentprocess).getWholeTime())
                {
                    currentprocess = i;
                }
                if (arrayList.get(i).getWholeTime()==arrayList.get(currentprocess).getWholeTime())
                {
                   int a = (int) (Math.random()*1000);                      //模擬進程條件相同,cpu隨便選取
                    if ((a&1)==0)
                    {
                        currentprocess =i;
                    }
                }
                i++;
            }
            //Process process = arrayList.get(currentprocess);
            int wholeTime = arrayList.get(currentprocess).getWholeTime();           //運行時間
            arrayList.get(currentprocess).setStarTime(nowtime);                     //設置實際開始時間
            nowtime+=wholeTime;                                                     //當前時間更新
            arrayList.get(currentprocess).setFinishTime(nowtime);                   //設置完成時間

            arrayList1.add(arrayList.get(currentprocess));                          //加入完成隊列
            arrayList.remove(currentprocess);                                       //等待隊列刪除;
            remain--;                                                               //剩餘進程--
        }
        double sumTurnaround_time=0;
        double sumTurnaround_time_withwight =0;
        for (int i = 0; i < arrayList1.size(); i++) {
            double Turnaround_time;
            double Turnaround_time_withwight;
            System.out.println("進程"+(i+1)+arrayList1.get(i).getProcessName()+"的開始時間爲");
            System.out.println(arrayList1.get(i).getStarTime());
            System.out.println("進程"+(i+1)+"的完成時間爲");
            System.out.println(arrayList1.get(i).getFinishTime());

            System.out.println("進程"+(i+1)+"週轉時間爲");
            Turnaround_time = arrayList1.get(i).getFinishTime() - arrayList1.get(i).getArrivalTime();
            sumTurnaround_time+=Turnaround_time;
            System.out.println(Turnaround_time);

            System.out.println("進程"+(i+1)+"帶權週轉時間爲");
            Turnaround_time_withwight = Turnaround_time / (double) arrayList1.get(i).getWholeTime();
            sumTurnaround_time_withwight+=Turnaround_time_withwight;
            System.out.println(Turnaround_time_withwight);
            System.out.println("----------------------------------------------");

        }
        System.out.println("先後順序爲:");
        for (int i = 0; i < arrayList1.size(); i++) {
            System.out.print(arrayList1.get(i).getProcessName()+" ");
        }
        System.out.println();
        System.out.println("這組進程的平均週轉時間爲");
        System.out.println(sumTurnaround_time / numofprocess);
        System.out.println("這組進程的平均帶權週轉時間爲");
        System.out.println(sumTurnaround_time_withwight / numofprocess);

    }
}

結果貼圖,

進程

簡單來說:C,D條件一樣,F,G條件一樣,所以會存在不同的結果;

結果一:

結果1表格

實際截圖

結果1

結果1.1
結果1.2

結果二:

結果二

實際截圖

結果2

結果2.1

結果2.2

實驗結果分析:

算法特點,針對不同情況有什麼樣的優劣
優點: 短進程優先嘛,所以短進程肯定運行的更順暢,更快結束;算法比較簡單,只要在隊列裏找到運行時間短的就可以啦

缺點:長進程很喫虧,可能會一直等待;完全不考慮等待時間,沒有優先級,也沒有緊迫感;需要預先知曉進程的運行所需時間;由於事先需要知曉運行時間,那麼人機交互基本就不可能啦;

實驗中發現的問題:

  1. Java中關於Collections.sort的用法;
  2. 關於相同條件進程的判斷;
  3. 進程太多,要輸入的太多,老是輸入錯誤;

實驗二模擬時間片輪轉調度

實驗源代碼

public class Process {            //進程部分加了運行時間的備份,另一個會在運行時減少;
           int wholeTimeBack;      //運行時間備份;
           public int getWholeTimeBack() {
           return wholeTimeBack;
    }
}
 public static void main(String[] args) {
        LinkedList<Process> linkedList = new LinkedList<>();
        Scanner in = new Scanner(System.in);
        System.out.println("請輸入有幾個進程呢?");
        int numberofprocess = in.nextInt();

        for (int i = 0 ; i<numberofprocess;i++)
        {
            System.out.println("請輸入進程"+(i+1)+"的進程名稱");
            String name = in.next();
            System.out.println("請輸入進程"+(i+1)+"的到達時間");
            int arrivalTime = in.nextInt();
            System.out.println("請輸入進程"+(i+1)+"的運行所需時間");
            int wholeTime = in.nextInt();
            Process process = new Process(name,arrivalTime,wholeTime);
            linkedList.add(process);
          //  System.out.println("----------------------------");
        }
        test(linkedList);
    }
    public static void test(LinkedList<Process> linkedList)
    {
        final  int slice = 1;                                   //時間片大小
        ArrayList<Process> arrayList = new ArrayList<>();       //存儲結果的容器
        Queue<Process> queue = new LinkedList<>();              //進程隊列
        int nowtime = 0 ;                                       //目前時間
        int numberOfProcess = linkedList.size();                //進程數目
        int numberOfPorcessback = numberOfProcess;
        Collections.sort(linkedList, new Comparator<Process>() {
            @Override
            public int compare(Process o1, Process o2) {
                return o1.getArrivalTime()<o2.getArrivalTime()?-1:1;
            }
        });

        while (numberOfProcess>0)
        {
            /*
            進程隊列有可能爲空,這時CPU空閒,我們從作業中提取一個;
             */
            if (queue==null||queue.size()==0)
            {
                queue.add(linkedList.peekFirst());
                linkedList.poll();
            }
            /*
            cpu空閒,時間就更改
             */
            if (nowtime<queue.peek().getArrivalTime()) {
                System.out.println("cpu"+nowtime+"~"+queue.peek().getArrivalTime()+"空閒");
                nowtime = queue.peek().getArrivalTime();
            }
            /*
            核心代碼
             */
            while (queue.size()!=0)
            {
                boolean flag = false;                                   //進程是否做完的標誌
                int currentwholetime = queue.peek().getWholeTime();     //當前所需要的運行時間
                queue.peek().setWholeTime(currentwholetime-slice);
                if (queue.peek().getWholeTime()<=0)                     //進程做完
                {
                    queue.peek().setWholeTime(0);                       //運行時間設置爲0;
                    numberOfProcess--;                                  //進程數--;
                    nowtime+=currentwholetime;
                    queue.peek().setFinishTime(nowtime);
                    arrayList.add(queue.poll());
                }
                else                                            //進程沒做完;
                {
                    flag = true;
                    nowtime+=slice;

                }

                while (linkedList.size()!=0&&linkedList.peek().getArrivalTime()<nowtime)
                {
                    queue.add(linkedList.pop());
                }
                /*
                這裏有兩種情形,一種是時間片用完的在先,一種是從作業到來的在先;
                 */
                if (flag)
                {
                    queue.add(queue.peek());
                    queue.poll();
                }
                while (linkedList.size()!=0&&linkedList.peek().getArrivalTime()==nowtime)
                {
                    queue.add(linkedList.pop());
                }
            }
        }
        double sumTurnaround_time=0;
        double sumTurnaround_time_withwight =0;
        for (int i = 0; i < arrayList.size(); i++) {
            Process process= arrayList.get(i);
            System.out.print(process.getProcessName()+"到達時間爲"+process.getArrivalTime()+" ");
            System.out.print("結束時間爲"+process.getFinishTime()+" ");
            System.out.print("週轉時間爲"+(process.getFinishTime()-process.getArrivalTime()+" "));
            double Turnaround_time=(double)(process.getFinishTime()-process.getArrivalTime());
            System.out.print("週轉時間"+Turnaround_time+" ");
            sumTurnaround_time+=Turnaround_time;
            double Turnaround_time_withwight= ((double)(process.getFinishTime()-process.getArrivalTime()))/(double)process.getWholeTimeBack();
            System.out.println("帶權週轉時間爲"+Turnaround_time_withwight+" ");
            sumTurnaround_time_withwight+=Turnaround_time_withwight;
            System.out.println();
        }
        System.out.println("--------------------------------");
        System.out.println("平均週轉時間爲"+sumTurnaround_time/numberOfPorcessback);
        System.out.println("平均帶權週轉時間爲"+ sumTurnaround_time_withwight/numberOfPorcessback);
    }
}

結果貼圖

時間片爲1:時間片優先級>新到達的進程

結果一

運行截圖:

結果1.1

時間片爲5: 時間片>新到達的進程;

結果2

運行截圖:

結果2.1

實驗結果分析:

算法特點:
優點:比較均衡,你做一下,我做一下;比較平均,算法也比較簡單實現;
缺點:時間一旦選的不好,就會造成不平衡的狀態;太短的話,等於一起做,先來後來沒有區別;太長的話,和依次做沒有區別,所以時間片必須選擇好;對緊急任務沒有反應,不適合緊急的任務;而且時間片輪轉,io操作怎麼辦,會有延遲,或者根本不讓io操作吧;

實驗中發現的問題

  1. 書上的例子不對
  2. 時間片用完和新進來的進程不知道選哪種;其實兩種就是調換一下代碼位置;
  3. 進程數量多的話,時間片短就會非常難算,所以就選擇了5個;
  4. 由於代碼完全沒有任何參考,所以有bug也說不定;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章