当前位置:   article > 正文

操作系统仿真实验(YTU)

操作系统仿真

实验一:资源分配仿真

实目的

在课程已经学习了死锁的4个必要条件的基础上,为了了解系统的资源分配情况,假定系统中任一资源在每一时刻只能由一个进程使用,任何进程不能抢占其它进程正在占有的资源,当进程得不到资源时,必须等待。因此,只要资源分配策略能保证不出现循环等待,系统就不会发生死锁。
要求学生编写和调试系统动态分配资源的仿真程序,观察死锁产生的条件,再采用适当的算法,有效地防止和避免死锁发生。
PS:实体类使用lombox自动生成getter setter 有参 无参方法(没有的手动生成)
lombox maven仓库地址

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.10</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
实现方式

随机分配算法产生死锁,银行家算法避免死锁

具体代码

随机分配算法:此算法不是模拟死锁而是会真正产生死锁(多运行几次随机的有的时候不会产生死锁)

package com.xu.demo.ytu.bank;

import java.util.ArrayList;
import java.util.List;


public class RandomAgl {
   
    public static Object A=new Object();
    public static Object B=new Object();
    public static Object C=new Object();
    public static Object D=new Object();

    public static void RanDomTest(List<Object> list){
   
        System.out.println(list);
        new Thread(()->{
   
            synchronized (A){
   
                System.out.println(Thread.currentThread().getName()+"我得到了资源:"+A);
                try {
   
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
                Object O=list.get((int) (Math.random() * 4));
                System.out.println("随机分配资源开始:线程"+Thread.currentThread().getName()+"随机去获取的资源是"+O);
                synchronized (O){
   
                    System.out.println("线程"+Thread.currentThread().getName()+"得到了资源"+O);
                }
            }
        }).start();

        new Thread(()->{
   
            Object O=list.get((int) (Math.random() * 4));
            synchronized (B){
   
                System.out.println(Thread.currentThread().getName()+"我得到了资源:"+B);
                try {
   
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
                System.out.println("随机分配资源开始:线程"+Thread.currentThread().getName()+"随机去获取的资源是"+O);
                synchronized (O){
   
                    System.out.println("线程"+Thread.currentThread().getName()+"得到了资源"+O);
                }
            }
        }).start();
    }

    public static void main(String[] args) {
   
        List<Object> testList=new ArrayList<>();
        testList.add(A);
        testList.add(B);
        testList.add(C);
        testList.add(D);
        RandomAgl.RanDomTest(testList);
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

运行截图
在这里插入图片描述死锁已经产生,接下来进入java的bin目录具体查看
在这里插入图片描述可以看出,线程1得到了资源270ca0并且想要去获取资源270c90,线程0得到了资源270c90并且想要获取资源270ca0死锁产生

银行家算法:
PCB类

package com.xu.demo.ytu.bank;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PCB {
   
    String processName;
    int maxUsed;
    int alreadyUsed;
    boolean isFinish;
    @Override
    public String toString() {
   
        return
                        "\t"+processName +
                        "               \t" + maxUsed +
                        "                       \t" + alreadyUsed +
                        "                       \t" +(maxUsed-alreadyUsed)+
                        "                   \t" + isFinish ;
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

BankAlg

package com.xu.demo.ytu.bank;

import java.util.*;

public class BankAlg {
   
    public static int availableSource = 10;
    public static ArrayList<String> safeList = new ArrayList<>();
    public static Map<String, PCB> pcbMap = new LinkedHashMap<>();

    /**
     * 初始化操作
     */
    public static void init() {
   
        PCB a = new PCB("A", 5, 1, false);
        PCB b = new PCB("B",  3, 1, false);
        PCB c = new PCB("C", 4, 2, false);
        PCB d = new PCB("D", 6, 3, false);

        pcbMap.put(a.processName, a);
        pcbMap.put(b.processName, b);
        pcbMap.put(c.processName, c);
        pcbMap.put(d.processName, d);
        System.out.println("---------------------------------------初始化--------------------------------------------------");
        System.out.println("进程名         " + "最大需求量            " + "占有量             " + "    仍需           " + "         完成");

        pcbMap.forEach((k, v) -> {
   
            System.out.println(v);
        });
        pcbMap.forEach((k, v) -> {
   
            availableSource -= v.alreadyUsed;
        });
        System.out.println("剩余资源量:" + availableSource);
    }

    /**
     *安全性检测算法
     */
    public static void safe(String pName, int pNum) {
   
        //请求的资源大于剩余资源,请求不安全,拒绝分配
        if (availableSource < pNum) {
   
            System.out.println("请求不安全 拒绝分配");
        } else {
   
            //尝试分配
            availableSource = availableSource - pNum;
            pcbMap.get(pName).alreadyUsed += pNum;
            //仍需资源如果为0,表明进程请求资源结束,进程释放资源
            if (pcbMap.get(pName).maxUsed - pcbMap.get(pName).alreadyUsed == 0) {
   
                availableSource += pcbMap.get(pName).maxUsed;
                pcbMap.get(pName).isFinish = true;
                pcbMap.get(pName).maxUsed = pcbMap.get(pName).alreadyUsed = 0;
            }
            //添加安全序列
            pcbMap.forEach((k, v) -> {
   
                if (v.maxUsed - v.alreadyUsed <= availableSource && !v.isFinish) {
   
                    safeList.add(k);
                }
            });
            //如果安全队列没有满,就说明当前分配资源可能不安全,继续尝试
            //找不到安全序列,拒绝请求
            if (safeList.size() == 0) {
   
                List<Boolean> checkList = new ArrayList<>();
                pcbMap.forEach((k, v) -> {
   
                    checkList.add(v.isFinish);
                });
                //如果安全序列全部完成不进行撤销
                System.out.println("请求不安全 拒绝分配");
                availableSource = availableSource + pNum;
                pcbMap.get(pName).alreadyUsed -= pNum;
                //这种情况比较特殊这时候对最后一个进程完成分配
                if (!checkList.contains(false)) {
   
                    availableSource = availableSource - pNum;
                    pcbMap.get(pName).alreadyUsed += pNum;
                }

            }
            //继续尝试分配
            int temp = 0;
            for (String s : safeList) {
   
                //在已经添加到安全序列的进程
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/997987
推荐阅读
相关标签
  

闽ICP备14008679号