模擬處理器調度

来源:https://www.cnblogs.com/Contra-A/archive/2019/11/08/11823214.html

一、實習內容 選擇一個調度演算法,實現處理器調度。 二、實習目的 在採用多道程式設計的系統中,往往有若幹個進程同時處於就緒狀態。當就緒進程個數大於處理器數時,就必須依照某種策略來決定哪些進程優先占用處理器。本實習模擬在單處理器情況下的處理器調度,幫助學生加深瞭解處理器調度的工作。 三、實習題目 本實習 ...


一、實習內容

選擇一個調度演算法,實現處理器調度。

二、實習目的

在採用多道程式設計的系統中,往往有若幹個進程同時處於就緒狀態。當就緒進程個數大於處理器數時,就必須依照某種策略來決定哪些進程優先占用處理器。本實習模擬在單處理器情況下的處理器調度,幫助學生加深瞭解處理器調度的工作。

三、實習題目

本實習有兩個題,學生可選擇其中的一題做實習。

第一題:設計一個按優先數調度演算法實現處理器調度的程式。

[提示]:

(1) 假定系統有五個進程,每一個進程用一個進程式控制制塊PCB來代表,進程式控制制塊的格式為:

進程名

指針

要求運行時間

優先數

狀態

其中,進程名——作為進程的標識,假設五個進程的進程名分別為P1,P2,P3,P4,P5

指針——按優先數的大小把五個進程連成隊列,用指針指出下一個進程的進程式控制制塊的首地址,最後一個進程中的指針為“0”。

要求運行時間——假設進程需要運行的單位時間數。

優先數——賦予進程的優先數,調度時總是選取優先數大的進程先執行。

狀態——可假設有兩種狀態,“就緒”狀態和“結束”狀態。五個進程的初始狀態都為“就緒”,用“R”表示,當一個進程運行結束後,它的狀態為“結束”,用“E”表示。

(2) 在每次運行你所設計的處理器調度程式之前,為每個進程任意確定它的“優先數”和“要求運行時間”。

(3) 為了調度方便,把五個進程按給定的優先數從大到小連成隊列。用一單元指出隊首進程,用指針指出隊列的連接情況。例:

 

  隊首標誌

         K2   

K1

P1

 K2

P2

 K3

P3

 

 K4

P4

 K5

P5

 

0

 

K4

 

K5

 

 

K3

 

K1

 

2

 

3

 

1

 

 

2

 

4

 

1

 

5

 

3

 

 

4

 

2

 

R

 

R

 

R

 

 

R

 

R

 

PCB1

 

PCB2

 

PCB3

 

 

PCB4

 

PCB5

 

(4) 處理器調度總是選隊首進程運行。採用動態改變優先數的辦法,進程每運行一次優先數就減“1”。由於本實習是模擬處理器調度,所以,對被選中的進程並不實際的啟動運行,而是執行:

優先數-1

要求運行時間-1

來模擬進程的一次運行。

提醒註意的是:在實際的系統中,當一個進程被選中運行時,必須恢復進程的現場,讓它占有處理器運行,直到出現等待事件或運行結束。在這裡省去了這些工作。

(5) 進程運行一次後,若要求運行時間¹0,則再將它加入隊列(按優先數大小插入,且置隊首標誌);若要求運行時間=0,則把它的狀態修改成“結束”(E),且退出隊列。

(6) 若“就緒”狀態的進程隊列不為空,則重覆上面(4)和(5)的步驟,直到所有進程都成為“結束”狀態。

(7) 在所設計的程式中應有顯示或列印語句,能顯示或列印每次被選中進程的進程名以及運行一次後進程隊列的變化。

(8) 為五個進程任意確定一組“優先數”和“要求運行時間”,啟動所設計的處理器調度程式,顯示或列印逐次被選中進程的進程名以及進程式控制制塊的動態變化過程。

package System;

public class Pcb{
    private String name;    //進程名
    private int time;       //進程時間
    private int priorty;    //優先數;
    private String status;  //狀態
    private Pcb pointer;    //指針

    public Pcb(String name, int time, int priorty, String status, Pcb pointer) {
        this.name = name;
        this.time = time;
        this.priorty = priorty;
        this.status = status;
        this.pointer = pointer;
    }
    public Pcb(){}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Pcb getPointer() {
        return pointer;
    }
    public void setPointer(Pcb pointer) {
        this.pointer = pointer;
    }
    public int getTime() {
        return time;
    }
    public void setTime(int time) {
        this.time = time;
    }
    public int getPriorty() {
        return priorty;
    }
    public void setPriorty(int priorty) {
        this.priorty = priorty;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }

    //顯示進程
    public void show() {
        System.out.println("進程" + name + ", 指針->" + pointer.getName() + ", 進程時間=" + time + "," +
                " 優先數=" + priorty+ ", 狀態=" + status );
    }
}
package System;

import java.util.Iterator;
import java.util.LinkedList;


public class Operate {
    LinkedList<Pcb> TotalPcb =new LinkedList<Pcb>();  //創建存儲PCB的隊列
    Pcb nullPcb = new Pcb("0", 0, 0, "E", null);//創建一個空PCB對象

    //創建PCB進程
    public void CreatePcb(int n){
        for(int i=1;i<=n;i++){
            Pcb pcb=new Pcb();
            pcb.setName("p"+i);
            int priorty=(int)(Math.random()*10);    //產生隨機優先數
            int time=(int)(Math.random()*10)+1;        //產生隨機時間數
            pcb.setPriorty(priorty);
            pcb.setTime(time);
            pcb.setPointer(nullPcb);
            pcb.setStatus("R");
            TotalPcb.add(pcb);
        }
    }

    //顯示PCB隊列
    public void showPcb(){
        Iterator<Pcb> p=TotalPcb.iterator();
        while(p.hasNext()){
            Pcb pcb=p.next();
            pcb.show();
        }
        System.out.println();
    }

    //刪除PCB隊列中運行結束的進程
    public void remove(){
        for(int i=0;i<TotalPcb.size();i++){
            if(TotalPcb.get(i).getStatus()=="E"){
                System.out.println(TotalPcb.get(i).getName()+"運行結束,退出隊列");
                TotalPcb.remove(i);
            }
        }
    }

    //運行後優先數-1,時間-1
    public void renew(Pcb p) {
        if (p.getPriorty()>0) {
            p.setPriorty(p.getPriorty()-1);  //優先數-1
        }
        if (p.getTime()>0) {
            p.setTime(p.getTime()-1);        //時間-1
        }
        if (p.getTime()==0){
            p.setStatus("E");            //若時間=0,狀態置E
        }
    }

    //隊列排序
    public void sortPcb() {
        for(int i=0;i<TotalPcb.size();i++) {
            for(int j=i+1;j<TotalPcb.size();j++) {
                if(TotalPcb.get(i).getPriorty()<TotalPcb.get(j).getPriorty()) {
                    //優先數大的先運行
                    Pcb temp=TotalPcb.get(i);
                    TotalPcb.set(i, TotalPcb.get(j));
                    TotalPcb.set(j, temp);
                }else if(TotalPcb.get(i).getPriorty()==TotalPcb.get(j).getPriorty()&&TotalPcb.get(i).getTime()>TotalPcb.get(j).getTime()) {
                    //優先數相同,時間最少的先運行
                    Pcb temp=TotalPcb.get(i);
                    TotalPcb.set(i, TotalPcb.get(j));
                    TotalPcb.set(j, temp);
                }
            }
        }
        //進程指針指向下一個進程
        for (int k =0;k<TotalPcb.size()-1; k++) {
            TotalPcb.get(k).setPointer(TotalPcb.get(k+1));
        }
        //最後一個進程指向為0
        if(TotalPcb.size()!=0){
            TotalPcb.get(TotalPcb.size()-1).setPointer(nullPcb);
        }
    }

    //進程運行
    public void run(){
        sortPcb();   //排序
        System.out.println("********************************************************");
        while(TotalPcb.size()!=0){
            System.out.println("運行前進程隊列:");
            showPcb();  //顯示隊列
            System.out.println(TotalPcb.get(0).getName()+"進程運行,運行時間-1,優先順序-1");
            renew(TotalPcb.get(0));
            System.out.print(TotalPcb.get(0).getName()+"進程運行之後:");
            TotalPcb.get(0).show();
            remove();  //刪除PCB隊列中運行結束的進程
            sortPcb();
            System.out.println("\n運行後進程隊列:");
            showPcb();
            System.out.println("********************************************************");
        }
        System.out.println("所有進程已運行完畢");

    }
}
package System;

        import java.util.Scanner;

public class Test
{
    public static void main(String[] args) {
        Scanner input =new Scanner(System.in);
        Operate op=new Operate();
        System.out.print("請輸入進程數:");
        op.CreatePcb(input.nextInt());
        op.run();
    }
}

 


您的分享是我們最大的動力!

更多相關文章
  • Python實戰教程,用Python做列印日曆的小程式,使用者可以通過輸入年月信息,程式將會輸出這個月的日曆 ...
  • 首先來總結一下,ArrayList的一些特點: 1.arraylist本質上就是一個elementData數組,它允許對元素進行快速隨機訪問,可以存放null值; 2.arraylist區別於數組的地方在於能夠自動擴展大小,其中關鍵就是grow() 方法,每次擴充後數組為原來數組的1.5倍; 3.a ...
  • 前言 array,顧名思義,數組,就是存儲數字、處理數字的一種數據結構。今天在將list轉換為array時,遇到了一個問題,數據量比較大,剛開始怎麼都不知道問題出在哪裡。直到我用一個3 3的小數據測試時,才發現問題的本質所在。浪費了半天的時間,不過總算搞明白了。 學的不夠踏實,以此警戒所有的初學者: ...
  • Python 3最重要的新特性之一是對字元串和二進位數據流做了明確的區分。文本總是Unicode,由str類型表示,二進位數據則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes,你不能拼接字元串和位元組流,也無法在位元組流里搜索字元串(反之亦然),也不能將字元串傳入參數為 ...
  • Python編寫類的時候,每個函數參數第一個參數都是self,一開始我不管它到底是幹嘛的,只知道必須要寫上。後來對Python漸漸熟悉了一點,再回頭看self的概念,似乎有點弄明白了。 首先明確的是self只有在類的方法中才會有,獨立的函數或方法是不必帶有self的。self在定義類的方法時是必須有 ...
一周排行
  • 1. 運行效果 在 "使用GetAlphaMask和ContainerVisual製作長陰影(Long Shadow)" 這篇文章里我介紹了一個包含長陰影的番茄鐘,這個番茄鐘在狀態切換時用到了翻轉動畫,效果如上所示,還用到了彈簧動畫,可以看到翻轉後有點回彈。本來打算自己這個動畫效果寫的,但火火已經寫 ...
  • 接上一篇,es部署很簡單,很快就弄好了。 但是還是有很多不玩美。 比如說:主機是本地的IP或機器名,埠是固定的9200. 而且是只有一個節點,我要在一臺機器上部署多個節點呢。 經過一段時間的摸索,做起來也很簡單,但過程切實很痛苦。 具體做法是:你想部署多少個節點,你就重覆多少次上一步的做法。啟動就 ...
  • 在項目中,需要為所有的Button、TextBox設置一個預設的全局樣式,一個個的為多個控制項設置相同的樣式顯然是不明智的。在WPF中可以通過資源設置全局樣式,主要有倆種方法: 1.第一種就是先寫好按鈕的樣式,不寫Key,然後在App.xaml中引用。 <ResourceDictionary xmln ...
  • 說明:該篇隨筆的代碼內容並非出自本人,是在其他網站搜尋的,出處已經不記得了,本次隨筆只為記錄,目的幫助自己,幫助他人。 實現的原理也不做多的贅述,直接上代碼。 第一個類是需要用到的Windows API public class Win32Api { [StructLayout(LayoutKind ...
  • 前言 在ASP.Net Core2.X調用的CreateWebHostBuilder和3.X的主要區別在於WebHost的調用,CreateDefaultBuilder被Host替換,另一個區別是對ConfigureWebHostDefaults()的調用; 由於新的主機生成器是通用主機生成器,因此 ...
  • 對於開發人員來說,常常需要在不藉助任何Microsoft Office及其他第三方軟體的情況下,打開、創建、修改、轉換、列印、瀏覽(Word、Excel、PowerPoint和PDF等)文檔,以及將數據從數據源轉換為常用的文檔格式,甚至一些其他的文檔操作。 在這裡,小編調查了業內許多開發人員,為大家 ...
  • 這次的目標是實現通過標註Attribute實現緩存的功能,精簡代碼,減少緩存的代碼侵入業務代碼。 緩存內容即為Service查詢彙總的內容,不做其他高大上的功能,提升短時間多次查詢的響應速度,適當減輕資料庫壓力。 在做之前,也去看了EasyCaching的源碼,這次的想法也是源於這裡,AOP的方式讓 ...
  • 例如想獲取尾碼名為.txt的文件 第一種方法獲取到的是對應的文件路徑 第二種方法可以獲取到文件的一些詳細信息 類似於"*.txt" 要與路徑中的文件名匹配的搜索字元串。這個參數可以包含有效的文本路徑和通配符(*和?)的組合人物,但它不支持正則表達式。 我是參照此路徑編寫的博客,用於自己查詢快速 ht ...
  • 我們在開發中Json傳輸數據日益普遍,有很多關於Json字元串的序列化和反序列化的文章大多都告訴你怎麼用,但是卻不會告訴你用什麼更高效。因為有太多選擇,人們往往會陷入選擇難題。 相比.NET Framework有三種選擇而.net core下已經沒有JavaScriptSerializer,但是大家 ...
  • c#微信公眾號開發 基本設置 參考微信官方文檔 https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html 開發→基本配置 公眾號開發信息 註:1.記錄好開發者密碼,會在程式中驗證過程 ...
x