模擬處理器調度

来源: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();
    }
}

 


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

更多相關文章
  • 一.docker簡介 1、docker定義:docker是一個用來裝應用的容器,就像杯子可以裝水,筆筒可以裝筆,書包可以放書一樣。你可以把“Hello World!”放到docker中,也可以把網站放到docker中,你可以把任何你想到的程式放到docker中。 2、docker思想: (1)集裝箱 ...
  • 智力題目有三個容積分別為3升、5升、8升的水桶,其中容積為8升的水桶中裝滿了水,容積為3升和容積為5升的水桶都是空的。三個水桶都沒有刻度,現在需要將大水桶中的8升水等分成兩份,每份都是4升水,附加條件是只能這三個水桶,不能藉助其他輔助容器。“恩,是的,這是一個很經典的問題。”“然而,我們並不能想全, ...
  • 今天,在Anaconda prompt啟動python遇到瞭如下錯誤: UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xaf in position 553: illegal multibyte sequence 看了看出錯跟蹤,查看瞭如下位置 ...
  • 許多小伙伴對於java中的三種初始化塊的執行順序一直感到頭疼,接下來我們就來分析一下這三種初始化塊到底是怎麼運行的。有些公司也會將這個問題作為筆試題目。 下麵通過一段代碼來看看創建對象時這麼初始化塊是如何運行的 package com.hxy; public class CodeBlock{ pub ...
  • 字元串或串(String)是由數字、字母、下劃線組成的一串字元。一般記為 s=“a1a2···an”(n>=0)。它是編程語言中表示文本的數據類型。在程式設計中,字元串(string)為符號或數值的一個連續序列,如符號串(一串字元)或二進位數字串(一串二進位數字)。 String類型你一定不陌生,畢 ...
  • 我們知道,swoole中有兩大進程,分別是 master 主進程和 manager 管理進程。 其中 master 主進程中會有一個主 reactor 線程和多個 reactor 線程,主要的作用就是用來維護TCP連接,處理網路IO,收發數據。 而 manager 管理進程,作用則是 fork 和管 ...
  • 1. random模塊 導入的是random模塊,格式是: import random 1.1 隨機小數 取隨機小數 : 數學計算。 print(random.random()) # 取0-1之間的小數print(random.uniform(1,2)) # 取1-2之間的小數 1.2 隨機整數 取 ...
  • 一、阻塞隊列:用於保存等待執行的任務。在阻塞隊列中,線程阻塞的兩種情況: 1.當隊列中沒有數據的情況下,消費者端的所有線程都會被自動阻塞(掛起),直到有數據放入隊列。 2.當隊列中填滿數據的情況下, 生產者端的所有線程都會被自動阻塞,知道隊列中有空位置,線程被自動喚醒。 二、阻塞隊列的主要方法 拋出 ...
一周排行
  • C 語法糖——持續更新 1. return的switch寫法 ...
  • 0. 前言 繼上一篇,以及上上篇,我們對SqlSugar有了一個大概的認識,但是這並不完美,因為那些都是理論知識,無法描述我們工程開發中實際情況。而這一篇,將帶領小伙伴們一起試著寫一個能在工程中使用的模板類。 1. 創建一個Client SqlSugar在操作的時候需要一個Client,用來管理數據 ...
  • 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //數組:長度不可變,類型單一 6 //ArrayList集合:長度可以任意改變,類型可以不單一 7 8 //創建一個ArrayList對象 9 ArrayList mylist ...
  • .NET 程式下銳浪報表 (Grid++ Report) 的綠色發佈指南 在銳浪報表官方為 CSharp 編寫的開發文檔:“在C#與VB.NET中開始使用說明.txt” 中,關於發佈項目是這麼描述的: ★發佈你的項目,用VS.NET製作安裝程式:1、先創建安裝項目:在解決方案資源管理器的根節點上點右 ...
  • 執行代碼清理時,可以點擊那個掃把小圖片,會按照預設的第一種配置文件來自動修複。也可以點擊下拉三角符合,選擇不同的配置文件,然後進行修複。或者快捷鍵Ctrl+K,Ctrl+E。 針對每一項配置的說明: 刪除不必要的using 儘可能將私有欄位設置為只讀 刪除不必要的類型轉換(針對強類型轉換),像Con ...
  • 1.概念簡述 (1)AR模型 AR 模型(auto regressive model)自回歸模型,模型參量法高解析度譜分析方法之一,也是現代譜估計中常用的模型。 用AR模型法求信具體作法是: ①選擇AR模型,在輸入是衝激函數或白雜訊的情況下,使其輸出等於所研究的信號,至少,應是對該信號的一個好的近似 ...
  • 4.元組 元組的主要特性為: 1.元組在創建之後,具有不可以更改的特性,因此不能直接給元組的元素賦值 2.元組的元素類型可以為任意類型,如字典、字元串、列表等 3.元組常用於在程式的整個生命周期中都不變的場景中 4.1 常用方法 元組大小和內容在定義賦值之後,就不可更改,常用的方法如下所示: cou ...
  • 老孟導讀:今天分享一個類似“孔雀開屏”的動畫效果,打開新的頁面時,新的頁面從屏幕右上角以圓形逐漸打開到全屏。 先來看下具體的效果 不知道這種效果大家叫什麼名字?如果有更合適的名字可以在評論處告訴我,下麵來說下如何實現此效果。 在使用Navigator進入一個新的頁面時,通常用法如下: 就包含了切換頁 ...
  • hashCode() 和equals() 方法的重要性體現在什麼地方? Java中的HashMap使用hashCode()和equals()方法設置值,根據鍵獲取值的時候也會用到這兩個方法。 怎樣 設置 的值? hashCode()獲得 hash值。而hash值用來確定hashmap中內部 Node ...
  • IDEA一些不錯的插件分享 目錄 IDEA一些不錯的插件分享 插件集合 CamelCase Translation LiveEdit MarkDown Navigator Jrebel CheckStyle IDEA Alibaba Java Coding Guidelines Ideavim Ma ...