Deadlock Avoidance - bankers algorithm

Deadlock
blocking problems to two or more threads in the implementation process due to competition resources caused by the absence of external force, they will not be able to promote it, then the system is in deadlock state.
Safety sequences
safe sequence refers to the current process of discharging a sequence of application resources, ensure the completion of the process in accordance with the sequence of allocating resources, deadlock will not occur
we assume that the process P1, P2, ... Pn
are required to meet safety sequence: Pi (1 < = i <= n) requires resources <+ = remaining resources allocated to Pj (1 <= j <i ) resources

Examples

Process Allocation Need Available
P0 0 0 3 2 0 0 1 2 1 6 2 2
P1 1 0 0 0 1 7 5 0
P2 1 3 5 4 2 3 5 6
P3 0 3 3 2 0 6 5 2
P4 0 0 1 4 0 6 5 6

Using bankers algorithm

Process Work Allocation Need Available
P0 1 6 2 2 0 0 3 2 0 0 1 2 1 6 5 4
P3 1 6 5 4 0 3 3 2 0 6 5 2 1 9 8 6
P4 1 9 8 6 0 0 1 4 0 6 5 6 1 9 9 10
P1 1 9 9 10 1 0 0 0 1 7 5 0 2 9 9 10
P2 2 9 9 10 1 3 5 4 2 3 5 6 3 12 14 14

Let's analyze the banker's algorithm
existing resources for 1654, P0 thread needs to 0012, assigned to it enough, we assign to the thread P0, P0 run until complete recovery of resources, Avaliable to 1654.
The thread then P1, requires resources 1 7 5 0, Avaliable <Need , not allocated
thread P2 requires resources 2 3 5 6, Avaliable <Need , not allocated
thread P3 requires resources 0652 allocated to it and then recovering resources, avaliable as 1986
threads P4 requires resources 0656 allocated to it and then recovering resources, avaliable as 19,910
returns continue determining P1, requires resources 1750 allocated to it and then recovering resources, avaliable to 299 10
then P2, requires resources 2356, and then recovering the resources allocated to it, is avaliable 3,121,214
Here Insert Picture Description
using java bankers algorithm implemented at

package com.os;
import java.util.Scanner;

/**
 * Description:v银行家算法
 *
 * @author:仙女萌
 * @Date 2018/12/29 16:32
 */
public class BankerAlgorithm {
    private static Scanner scanner = new Scanner(System.in);
    //资源数量
    private int resource;
    //线程数量
    private int thread;
    //资源总数量
    private int max[];
    //剩余资源数量
    private int avilable[];
    //最大需求矩阵
    private int[][] applymax;
    //已分配资源数量
    private int[][] allocation;
    //还需要资源是数量
    private int need[][];
    boolean F[];
    /**
     * 一维数组的输入
     * @param n
     * @return
     */
    private int[] inputone(int n){
        int[] number = new int[n];
        for(int i = 0;i < resource;i++){
            number[i] = scanner.nextInt();
        }
        return number;
    }
    /**
     * 二维数组的输入
     * @param m
     * @param n
     * @return
     */
    private int[][] inputtwo(int m,int n){
        int[][] number = new int[m][n];
        for(int i = 0;i < m;i++){
            System.out.print("进程p"+i+":");
            for(int j = 0;j < n;j++){
                number[i][j] = scanner.nextInt();
            }
        }
        return number;
    }
    /**
     * 数组的初始化
     */
    public void init(){
        System.out.print("请输入资源数量:");
        resource = scanner.nextInt();
        System.out.print("请输入线程数量:");
        thread = scanner.nextInt();
        System.out.print("请输入最大资源数量:");
        max = inputone(resource);
        System.out.println("请输入每个线程最大申请资源总数");
        applymax = inputtwo(thread,resource);
        System.out.println("请输入资源分配情况");
        allocation = inputtwo(thread,resource);
        //剩余资源
        avilable = max.clone();
        for(int i = 0;i < resource;i++){//资源个数
            for(int j = 0;j < thread;j++){//线程个数
                avilable[i] -= allocation[j][i];
            }
        }
        need = new int[thread][resource];
        //还需要资源need = apply-allocation
        for(int i = 0;i < thread;i++){
            for(int j = 0;j < resource;j++){
                need[i][j] = applymax[i][j] - allocation[i][j];
            }
        }
        F = new boolean[thread];
        show();
        System.out.println("安全性检查");
        int[] work = avilable.clone();
        safe(work,allocation,need);
    }
    /**
     * 输出
     */
    private void show(){
        int[] work = avilable.clone();
       //最大资源数量
        System.out.print("资源总数:");
        for(int i = 0; i < resource; i++){
            System.out.print(max[i]+"  ");
        }
        System.out.println();
        System.out.print("可利用资源向量:");
        for(int j = 0;j < resource;j++){
            System.out.print(work[j]+" ");
        }
        System.out.println();
        System.out.println("NAME"+"\t\t"+"MAX"+"\t\t"+"ALLOCATION1"+"\t\t"+"NEED");
        for(int i = 0 ;i < thread;i++){//线程
                System.out.print("p"+i+"\t\t\t");
           for(int j = 0;j <resource;j++){
               System.out.print(applymax[i][j]+" ");
           }
            System.out.print("\t\t");
            for(int j = 0;j < resource;j++){
                System.out.print(allocation[i][j]+" ");
            }
            System.out.print("\t\t");
            for(int j = 0;j <resource;j++){
                System.out.print(need[i][j]+" ");
            }
            System.out.println();
        }
    }
    /**
     * 安全性算法
     * @return
     */
    public boolean safe(int[] work,int[][] allocation,int[][] need){
        boolean s = true;
        int count = 0;
        int count1 = -1;
        for(int i = 0;i <thread;i++){
            F[i] = false;
        }
       // System.out.println("还原finish");
        System.out.println("name"+"\t\t"+"WORK"+"\t\t"+"NEED"+"\t\t"+"ALLOCATION"+"\t\t\t"+"WORK+ALLOCATION"+"\t\t"+"FINISH");
        int way[] = new int[thread];
        for(int i = 0;i < thread;i++) {
            s = true;
       //判断资源是否足够分配
            for (int j = 0; j < resource; j++) {
                if (work[j] < need[i][j]) {//avaliable <need
                    s = false;
                    break;
                }
            }
            // System.out.println(i+"检查完毕  s =="+s+" "+"F[i] ==" +F[i]);
            //资源足够分配,那么就分配资源
            if (s == true && F[i] == false) {
                F[i] = true;
                way[count++] = i;
                System.out.print("p"+i+"\t\t\t");

                for (int j = 0; j < resource;j++) {
                    System.out.print(work[j]+" ");
                }
                System.out.print("\t\t");
                for (int j = 0; j < resource; j++) {
                    System.out.print(need[i][j]+" ");
                }
                System.out.print("\t\t");
                for (int j = 0; j < resource; j++) {
                    System.out.print(allocation[i][j]+" ");
                }
                System.out.print("\t\t\t\t");
                for (int j = 0; j < resource; j++) {
                    work[j] = work[j] + allocation[i][j];
                    System.out.print(work[j]+" ");
                }
                System.out.print("\t\t\t\t");
                System.out.println(F[i]);
            }
            /**
             * 如果循环一遍没有任何的线程被分配资源,那么这个线程是不安全的
             */
            if (i == thread - 1 && count == count1) {
                System.out.println("该线程不安全");
                return false;
            }
            /**
             * 从头再继续循环
             */
            if (count < thread && i == thread - 1) {
               // System.out.println("count < thread && i == thread - 1");
                count1 = count;
                i = -1;
            }
            if (count == thread) {
                System.out.print("该线程的安全序列为:");
                for (int j = 0; j < thread; j++) {
                    System.out.print(way[j]+"  ");
                }
                System.out.println();
                return true;
            }
        }
        return false;
    }

    public boolean update(int p,int[] request){
        for(int i = 0;i < resource;i++){
            if(request[i] > need[p][i]){
                System.out.println("线程不安全");
                return false;
            }
            if(request[i] > avilable[i]){
                System.out.println("线程不安全");
                return false;
            }
        }
         return true;
    }


    /**
     * 预分配
     */
    public void preAll(){
        boolean b = true;
        // 预分配资源
        System.out.print("请选择进程申请资源: p");
        int p = scanner.nextInt();
        int[] request = new int[resource];
        System.out.print("申请资源数:");
        request = inputone(resource);//需要请求的资源
        int[] work1 = avilable.clone();
        int [][] all = allocation.clone();
        int n[][] = need.clone();
        int[] work2 = avilable.clone();
        /**
         * 输入合法
         */
        if(update(p,request) == true){
            //预分配
            for(int i = 0;i < resource;i++){
                work1[i] = work1[i] - request[i];
                all[p][i] = all[p][i] + request[i];
                n[p][i] =  n[p][i] - request[i];
                if(n[p][i] != 0){//数据不为0
                    b = false;
                }
            }
            if(b == true){//进程可以运行完毕
                for(int i = 0;i < resource;i++){
                    work1[i] = all[p][i]+work1[i];
                    all[p][i] = 0;
                }
            }
        }


        work2 = work1.clone();
        //public boolean safe(int[] work,int[][] allocation,int[][] need){
        if(safe(work2,all,n)){//安全性检查
           //线程安全2
            avilable= work1.clone();
            allocation = all;
            need = n;
        }
        show();
    }

    public void menu(){
        while(true){
            System.out.print("是否预分配(Y/N):");
            char ch = scanner.next().charAt(0);
            switch (ch){
                case 'Y':
                    preAll();//预分配
                    break;
                case 'N':
                    System.out.println("退出系统");
                    System.exit(0);
                    break;
                default:
                    System.out.print("输入不合法,重新输入:");
                    break;
            }
        }
    }
    public static void main(String[] args) {
        BankerAlgorithm banker = new BankerAlgorithm();
        banker.init();
        banker.menu();
    }
 }

operation result:
Here Insert Picture Description
Here Insert Picture Description

Guess you like

Origin blog.csdn.net/Alyson_jm/article/details/89603080