死锁:

死锁产生的现场:当A进程P S2信号量而B进程P S1信号量时就会产生死锁,因为S2信号量需要B进程释放,而S1信号量需要A进程释放,因此两个进程都在等相互的资源,造成死锁。

死锁产生的条件:

互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。(信号量s1 s2为互斥的信号量,只能被一个进程占用)

请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。(A进程在获取s2阻塞时,一直占用s1)

不可剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。(s1只能由A进程释放,s2只能由B进程释放)

环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。(A B 进程都是环形链路)

避免死锁的算法:

银行家算法是避免死锁的一种重要方法,防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。通过这个算法可以用来解决生活中的实际问题,如银行贷款等。

程序实现思路银行家算法顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行加资金无法周转而倒闭,对每一笔贷款,必须 考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还 资源,以供其他进程使用资源。如果资源分配不得到就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。
把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满 足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,,每个进程的资源需求总量不能超过系统拥有的资源总 数, 银行算法进行资源分配可以避免死锁.
 
一.程序流程图:
1.初始化算法流程图:

2.银行家算法流程图:

 3.安全性算法流程图:

二.银行家算法设计:
1.设进程i提出请求Request[n],则银行家算法按如下规则进行判断。
(1)如果Request[n]>Need[i,n],则报错返回。
(2)如果Request[n]>Available,则进程i进入等待资源状态,返回。
(3)假设进程i的申请已获批准,于是修改系统状态:
    Available=Available-Request
    Allocation=Allocation+Request
    Need=Need-Request
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
2.安全性检查
(1)设置两个工作向量Work=Available;Finish =False
(2)从进程集合中找到一个满足下述条件的进程,
   Finish =False
   Need<=Work
   如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
    Work=Work+Allocation
    Finish=True
    GO TO 2
(4)如所有的进程Finish =true,则表示安全;否则系统不安全。
3.数据结构
假设有M个进程N类资源,则有如下数据结构:
#define W 10
#define R 20
int A ;                      //总进程数
int B ;                     //资源种类
int ALL_RESOURCE[W];        //各种资源的数目总和
int MAX[W] ;             //M个进程对N类资源最大资源需求量
int AVAILABLE ;          //系统可用资源数
int ALLOCATION[W] ;      //M个进程已经得到N类资源的资源量
int NEED[W] ;            //M个进程还需要N类资源的资源量
int Request ;            //请求资源个数
5.4主要函数说明
void showdata();           //主要用来输出资源分配情况
void changdata(int);       //主要用来输出资源分配后后的情况
void rstordata(int);       //用来恢复资源分配情况,如:银行家算法时,由于分配不安全则要恢复资源分配情况
int chkerr(int);           //银行家分配算法的安全检查
void bank()   ;             //银行家算法
银行家算法的课程设计(二)VC++6.02008-01-28 15:29源程序
数据结构分析:
假设有M个进程N类资源,则有如下数据结构:
#define W 10
#define R 20
int A ;                      //总进程数
int B ;                     //资源种类
int ALL_RESOURCE[W];        //各种资源的数目总和
int MAX[W] ;             //M个进程对N类资源最大资源需求量
int AVAILABLE ;          //系统可用资源数
int ALLOCATION[W] ;      //M个进程已经得到N类资源的资源量
int NEED[W] ;            //M个进程还需要N类资源的资源量
int Request ;            //请求资源个数
第3章   程序清单#include <iostream>
using namespace std;
#define MAXPROCESS 50                        /*最大进程数*/
#define MAXRESOURCE 100                        /*最大资源数*/
int AVAILABLE[MAXRESOURCE];                    /*可用资源数组*/
int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩阵*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*分配矩阵*/
int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩阵*/
int REQUEST[MAXPROCESS][MAXRESOURCE];        /*进程需要资源数*/
bool FINISH[MAXPROCESS];                        /*系统是否有足够的资源分配*/
int p[MAXPROCESS];                             /*记录序列*/
int m,n;                                    /*m个进程,n个资源*/
void Init();
bool Safe();
void Bank();
int main()
{
    Init();
    Safe();
    Bank();
}
void Init()                /*初始化算法*/
{
    int i,j;
    cout<<"\t---------------------------------------------------"<<endl;
    cout<<"\t||                                               ||"<<endl;
    cout<<"\t||                 银行家算法                    ||"<<endl;
    cout<<"\t||                                               ||"<<endl;
    cout<<"\t||                             计科04151  李宏   ||"<<endl;
    cout<<"\t||                                               ||"<<endl;
    cout<<"\t||                                  0415084211   ||"<<endl;
    cout<<"\t---------------------------------------------------"<<endl;
    cout<<"请输入进程的数目:";
    cin>>m;
    cout<<"请输入资源的种类:";
    cin>>n;
    cout<<"请输入每个进程最多所需的各资源数,按照"<<m<<"x"<<n<<"矩阵输入"<<endl;
    for(i=0;i<m;i++)
    for(j=0;j<n;j++)
    cin>>MAX[j];
    cout<<"请输入每个进程已分配的各资源数,也按照"<<m<<"x"<<n<<"矩阵输入"<<endl;
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>ALLOCATION[j];
            NEED[j]=MAX[j]-ALLOCATION[j];
            if(NEED[j]<0)
            {
                cout<<"您输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源数错误,请重新输入:"<<endl;
                j--;
                continue;
            }
        }
    }
    cout<<"请输入各个资源现有的数目:"<<endl;
    for(i=0;i<n;i++)
    {
        cin>>AVAILABLE;
    }
}
void Bank()                /*银行家算法*/
{
    int i,cusneed;
    char again;
    while(1)
    {
        cout<<"请输入要申请资源的进程号(注:第1个进程号为0,依次类推)"<<endl;
        cin>>cusneed;
        cout<<"请输入进程所请求的各资源的数量"<<endl;
        for(i=0;i<n;i++)
        {
            cin>>REQUEST[cusneed];
        }
        for(i=0;i<n;i++)
        {
            if(REQUEST[cusneed]>NEED[cusneed])
            {
                cout<<"您输入的请求数超过进程的需求量!请重新输入!"<<endl;
                continue;
            }
            if(REQUEST[cusneed]>AVAILABLE)
            {
                cout<<"您输入的请求数超过系统有的资源数!请重新输入!"<<endl;
                continue;
            }
        }
        for(i=0;i<n;i++)
        {
            AVAILABLE-=REQUEST[cusneed];
            ALLOCATION[cusneed]+=REQUEST[cusneed];
            NEED[cusneed]-=REQUEST[cusneed];
        }
        if(Safe())
        {
            cout<<"同意分配请求!"<<endl;
        }
        else
        {
            cout<<"您的请求被拒绝!"<<endl;
            for(i=0;i<n;i++)
            {
                AVAILABLE+=REQUEST[cusneed];
                ALLOCATION[cusneed]-=REQUEST[cusneed];
                NEED[cusneed]+=REQUEST[cusneed];
            }
        }
        for(i=0;i<m;i++)
        {
            FINISH=false;
        }
        cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl;
        cin>>again;
        if(again=='y'||again=='Y')
        {
            continue;
        }
        break;
        }
}
bool Safe()                                    /*安全性算法*/
{
    int i,j,k,l=0;
    int Work[MAXRESOURCE];                    /*工作数组*/
    for(i=0;i<n;i++)
    Work=AVAILABLE;
    for(i=0;i<m;i++)
    {
        FINISH=false;
    }
    for(i=0;i<m;i++)
    {    
        if(FINISH==true)
        {
            continue;
        }
        else
        {
            for(j=0;j<n;j++)
            {
                if(NEED[j]>Work[j])
                {
                    break;
                }
            }
            if(j==n)
            { 
                FINISH=true;
                for(k=0;k<n;k++)
                {
                    Work[k]+=ALLOCATION[k];
                }
                p[l++]=i;
                i=-1;
            }
            else
            {
                continue; 
            }
        }
        if(l==m)
        {
            cout<<"系统是安全的"<<endl;
            cout<<"安全序列:"<<endl;
            for(i=0;i<l;i++)
            {
                cout<<p;
                if(i!=l-1)
                {
                    cout<<"-->";
                }
            }
            cout<<""<<endl;
            return true;
        }
    }
    cout<<"系统是不安全的"<<endl;
    return false;

输出数据

银行家算法的模拟实现”是本学期操作系统课程唯一的课程设计。在设计此程序的过程中,我遇到过许多问题,也学到了很多东西。本程序的设计实现主要是用 C++语言实现,通过对程序算法的设计优化、输出显示的格式设计、输入过程中的异常处理等一些设计过程中的问题的考虑解决,在C++学习上也有了很大的进 步。程序设计过程中开始遇到的最大的问题是算法的结构设计问题,课本上只给了设计要求及简单的算法,要真正实现还需要考虑很多方面。在算法的数据结构设计 上考虑了很长时间。在程序设计中先后参考了很多网络资料,也参考了一些别人写的的程序,综合这些算法思想和自己的思路对程序做了很好的设计方式,对一些算 法的优越性等也作了一些考虑。此外考虑最多的就是异常错误处理的设计。一个好的程序必须能在各种环境下都有其相应的处理方式,至少能应对一些常见的可能发 生的错误。比如一般的要求输入为数字时,如果输入了一个非数字字符,程序就会立即出错无法继续运行,本程序针对这个问题设计了一个shuzi();函数进 行处理,处理方式为:接受键盘输入的字符为字符串,然后对字符串的每个字符进行判断是否为数字,如果有非数字字符出现则提示出错并要求重新输入。又如在判 断是否继续时要求输入Y/N时,按一般的方式,如果输入为多个字符,则多余的字符会保存在缓冲区,到下次要求输入时输入而导致出错,对此问题设计处理方式 为接受输入字符保存为串然后只取其首字符进行判断。还有很多类似的错误处理。还有在设置程序的显示优化时,发现暂停函数在不同的情况下执行顺序不同,如此 等等。在课程设计过程中遇到了许多问题,也向同宿舍的同学做了一些请教一起讨论,也因此从他们身上学到了许多东西。

转载于:https://www.cnblogs.com/quchengfeng/p/4939940.html

银行家算法:解决多线程死锁问题相关推荐

  1. 操作系统常问面试问题 3 —— 死锁(deadlock)(产生的条件、死锁避免(银行家算法)、死锁检测)

    死锁(产生的条件.死锁避免(银行家算法).死锁检测) 死锁(deadlock) 1.定义 2.产生的条件 3.死锁避免 3.1.银行家算法 3.1.1.实现过程 4.死锁检测 5.死锁恢复 6.鸵鸟算 ...

  2. 死锁-死锁预防、死锁避免(资源分配图与银行家算法)、死锁检测、死锁解除

    文章目录 1 死锁 2 死锁预防 3 死锁避免 4 死锁检测 5 死锁解除 6 参考文献 1 死锁 什么是死锁     通俗的讲,就是两个或多个进程无限期的阻塞.相互等待的一种状态.比如哲学家进餐问题 ...

  3. 避免死锁方法之银行家算法

    文章目录 死锁 银行家算法原理 银行家算法具体介绍 要介绍银行家算法应该先简单说一下死锁: 死锁 死锁概念:在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源时,就会造成 ...

  4. 避免死锁的银行家算法

    死锁的定义> 如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那仫该组进程就是死锁的. 产生死锁的必要条件> 1).互斥条件:进程对所分配到的资源进行排它性使用, ...

  5. 10 操作系统第二章 进程管理 死锁、死锁的处理策略 银行家算法

    文章目录 1 死锁 1.1 死锁定义 1.2 死锁.饥饿.死循环的区别 1.3 死锁产生的必要条件 1.4 什么时候会发生死锁 1.5 死锁的处理策略 1.6 死锁的概念小结 2 死锁预防 2.1 破 ...

  6. 【操作系统/OS笔记15】死锁的系统模型,死锁的处理办法,银行家算法与死锁检验算法

    本次笔记内容: 11.1 死锁问题 11.2 系统模型 11.3 死锁特征 11.4 死锁处理办法 11.5 死锁预防和死锁避免 11.6 银行家算法 11.7 死锁检测和死锁恢复 文章目录 死锁问题 ...

  7. 操作系统-死锁(预防、安全序列、银行家算法图解、检测及解除)

    目录 基本定义 死锁产生的原因 系统资源的竞争 进程推进顺序非法 死锁产生的必要条件 死锁的处理策略 死锁预防 破坏互斥条件 破坏不可剥夺条件 方案一 方案二 破坏请求并保持条件 破坏循环等待条件 避 ...

  8. 利用银行家算法避免死锁

    [概述] 操作系统中,银行家算法是避免死锁的一种重要算法. 本文针对<计算机操作系统(第四版)>(汤小丹)p123页的问题:**如果在银行家算法中把P0发出的请求向量改为Request0( ...

  9. C语言实现银行家算法

    一.银行家算法 1.由来 银行家算法最初是由荷兰计算机科学家艾兹赫尔·迪杰斯特拉(Edsger W. Dijkstra)于1965年提出的.当时他正致力于解决多道程序设计中产生的死锁问题.在多道程序设 ...

最新文章

  1. 如何将一个列表当作元组的一个元素
  2. rm 空间不释放_rm删除文件之后,空间就被释放了吗?
  3. 面向对象先导课程——PART3
  4. java web 嵌套播放器_请教一下tableau如何嵌套进自己开发的javaweb 项目中,谢谢了...
  5. jlink v9可升级固件‘_STM32WB的硬核功能 - 无线固件升级FUOTA
  6. 10 个实用的 GitHub 插件
  7. android 摇一摇动画效果,android 微信摇一摇动画效果
  8. NOIP2016-D2-T2 蚯蚓(单调队列)
  9. java数据结构- - - -栈
  10. 【Qt开发】Qt让线程休息一段时间
  11. 在C语言中如何高效地复制和连接字符串?
  12. 熠新科技亮相2019中国光纤传感学术会议暨产业化论坛
  13. 电脑自带的edge浏览器无法访问解决问题
  14. word文件退出只读模式
  15. VapourSynth压制教程 【Waifu2x N卡 放大教程】
  16. 【Linux_02】
  17. 一键u盘装win7系统教程图解
  18. 视频有水印不用怕,一键轻松解析视频水印,高清画质!
  19. java五大浏览器,[Java教程]各主流浏览器(PC、移动端)userAgent属性信息
  20. 第14章 LINQ to SOL

热门文章

  1. python实现局域网攻击_通过python实现DNS欺骗
  2. postgresql删除索引_PostgreSQL 13 发布,索引和查找有重大改进
  3. python循环删除包含字符串_删除包含完全字符串的文件中的行(Python)
  4. C语言结构体描述BMP的文件格式
  5. 苹果更新未知错误17_iOS 13 新功能,静音未知来电
  6. nginx tcp转发_Nginx学习(九):负载均衡服务
  7. java class api 中文乱码_SpringMVC之springmvc原始api,请求中文乱码问题
  8. mysql从库执行delete停止_MySQL主库大表执行delete语句,Ctrl+C具体发生了什么分析...
  9. linux wordpress伪静态,wordpress程序在win和Linux系统下的伪静态设置 - 张力博客
  10. linux 关于休眠得脚本,linux – 如果条件为true,请将cron作业休眠5分钟