模擬處理器調度

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

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


一、實習內容

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

二、實習目的

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

三、實習題目

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

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

[提示]:

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

 


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

-Advertisement-
Play Games
更多相關文章
  • 一.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.當隊列中填滿數據的情況下, 生產者端的所有線程都會被自動阻塞,知道隊列中有空位置,線程被自動喚醒。 二、阻塞隊列的主要方法 拋出 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...