银行家算法

周二晚才知道第四章小作业还有一道难度及工作量不亚于一个大作业的编程题..晚上找了一些资料,周三肝了一天算是赶完了这突如其来的ddl...

银行家算法是一种经典的死锁问题,下面是ppt里对银行家算法的描述。






查阅网上资料时,发现对于算法的代码有不少,但基于多线程的linux编程实现却很少,偶然发现了班上一大佬的文章,参考了他的思路(linux多线程模拟银行家算法
),结合了其他的一些资料,算是在ddl之前水完了这个作业...

这里记录一下一些细节和遇到的一些问题,以便日后回顾...(再次对上边的大佬进行无声的感谢..)

先贴代码为敬。

#include
#include
#include
#include
#include

#define true 1
#define false 0
#define MAXTN 10
#define MAXSRC 50   
typedef int bool;

int thnum;  //线程数目
int res;    //资源种类数 
int leftnum;    //结束的线程数 
int Available[MAXSRC];  //Available[j]:系统中j类资源空闲个数 
int Max[MAXTN][MAXSRC]; //Max[i][j]:线程i对j类资源的最大需求量
int Allocation[MAXTN][MAXSRC];  //Allocation[i][j]:线程i已分配j类资源的数量
int Need[MAXTN][MAXSRC];    //Need[i][j]:线程i还需要j类资源的数量  Need=Max-Allocation

int Work[MAXTN];    //工作向量 
bool visited[MAXTN];    //线程是否被访问过 
bool Finish[MAXTN]; //线程是否已结束
int Safeseries[MAXTN];  //安全序列 

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//初始化互斥锁
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//初始化条件变量 

void init() //初始化数据 
{
    printf("输入线程数目:\n");
    scanf("%d",&thnum);
    printf("输入资源种类数:\n");
    scanf("%d",&res);
    //init Available 
    printf("输入每类资源的可用数量:\n");
    for(int i=0;iAvailable[i])
            {
                printf("线程%d请求%d类资源数目大于该类资源剩余数量!\n",id,i);
                return 1;
            }
        }
        else
        {
            printf("线程%d请求%d类资源数目大于该线程所需资源数目!\n",id,i);
            return 1;
        }
     } 
     //step2 试分配并修改数据结构
    for(int i=0;i

运行截图如下:


整个代码的核心部分分为以下几个部分:

  • init()初始化算法
  • safe()安全性检测算法
  • banker()银行家算法主体
  • threadprocess()线程算法

程序运行过程大概就是:初始化(矩阵及数组信息、互斥锁及条件变量等)——创建线程——线程内部根据请求数执行银行家算法,进行安全性检测——线程条件满足结束或条件不满足等待——全部线程满足需求后程序退出。

把各个模块内部及模块间的关系理清一步一步做就很明确了。(这里再次感谢大佬的文章指导了我方向)

下面列举一下遇到的一些问题。
编译问题:
1.使用const int MAXTN=10; const int MAXSRC=50; 进行定义数组空间,编译会报错“Variably modified array at file scope”。
原因:使用const声明的对象是一个运行时对象,无法使用其作为某个量的初值、数组的长度等情形使用。详细原因参考 C语言编译错误:Variably modified array at file scope
使用#define宏定义即可解决。
2.在c语言中没有定义布尔类型,只有c++中有。C99标准后定义了bool类型变量,但需要引入头文件,所以只需使用typedef int bool #define true 1 #define false 0进行定义。
3.二维数组参数传递问题。compare函数中需要传递二维数组,但简单的使用int** Need编译会报错,错误原因好像是传递参数和函数所需参数类型不匹配,又吃了c语言基本功不扎实的亏...参数传递二维数组讲了几个方法,又引出了值传递、引用传递等不同传递方法,再次显示出当初给自己挖下的坑...值传递、地址传递、引用传递
4.若干语法错误...当在linux中用gcc编译后,一片的error吓懵我了,但其中很大一部分都是“缺少[]”或标点使用错误之类的低级错误..

算法问题:
1.对于资源请求Request数组的赋值。开始考虑使用随机数值来增加真实性,后来想想这个值应该是使用者输入决定的,如果随机产生可能会导致线程间死锁(很大概率)。
2.因为创建进程先后有顺序,导致进入互斥区的进程顺序固定,无法做到随机性。使用sleep()也不好掌握时机。(目前尚未解决)
3.以前没用到或很少用的函数:memset()用于初始化数组,使值清0。
4.一开始总是提示不安全状态,因为判断条件出错。当一个线程完成资源分配后结束,会使安全序列理论输出减少一个,故判断条件也应该是动态的,即使用一个leftnum记录剩余线程数,if(k==(thnum-leftnum))判断是否处于安全状态。

其他问题想到再补充吧,总之这个算法还不完善,有时间再回头看吧,毕竟是赶出来的...测试还有一些奇怪的地方没有解决...

你可能感兴趣的:(银行家算法)