多线程模拟客户实现银行家算法

多线程模拟客户实现银行家算法_操作系统

1. 主题:

多线程、防止竞态条件和死锁避免。

2. 目的:

多线程程序来实现银行家算法

3. 要求:

多个客户请求和释放银行资源,只有仍能使系统处于安全状态,银行家才会允许请求,会让系统处于非安全状态的请求都将被拒绝。

银行家:

银行家分析来自n个客户对m个资源类型的请求,首先银行家将使用一下数据结构来跟踪资源:

客户:

创建n个客户线程,以便请求和释放资源:
描述

客户不断的循环:请求在释放随机数量的资源,客户的资源请求不超过他们的数组Need的相应值。如果一个请求满足安全算法,那么银行家将会允许他,如果一个请求不能将系统保持在安全状态,那么银行家将拒绝他,请求和释放资源的原型如下:
request_resources()函数:
在这里插入图片描述
release_resources()函数
在这里插入图片描述

互斥锁:

采用互斥锁来控制访问,以便防止竞争条件。
具体上锁的位置可以理解为,只要是对共享资源的操作就加锁,操作完成就解锁。
有些特殊的输出也可以对其进行加锁,这样可以保证是原子输出,不会被其他线程横插一杠,打乱我们应有的输出,到时候调试都不好调试。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <omp.h>
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <semaphore.h>

#define Num_Cus 5  //客户数量
#define Num_Res 3  //资源数量

//每种资源可用实例数量
int ava[Num_Res] ;//= {3,3,2};                   
//每个进程的最大需求
int max[Num_Cus][Num_Res] = { {7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3} }; 
//每个进程现在分配的每种资源类型的实例数量         
int allocation[Num_Cus][Num_Res] = { {0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2} };   
//max-allocation
int Need[Num_Cus][Num_Res];   
//记录安全序列      
int arr[Num_Cus];


pthread_mutex_t mutex;
pthread_cond_t cond;

int isless(int a[],int b[],int n){      //判断a数组是不是全部小于b数组
    int flag = 1;
    for(int i=0;i<n;i++){
        if(a[i]>b[i]){
            flag = 0;
            break; 
        }
    }
    return flag;
}

int issafe(){
    int flag = 0;   //判断是否是安全状态
    int num = 0;
    int Work[Num_Res];
    int  Finish[Num_Cus];
    memset(Finish,0,sizeof(int)*Num_Cus);//初始化Finish数组
    //Finish[customer_num] = 1;
    for(int i=0;i<Num_Res;i++){         //初始化Work数组
        Work[i] = ava[i];
    }
    int i = 0;
    int x = 0;
    for(i=0;i<Num_Cus;i++){
        if(Finish[i]==0&&isless(Need[i],Work,Num_Res)){
            arr[x] = i;
            x++;
            //printf("i: %d\n",i);
            //printf("work:");
            for(int j=0;j<Num_Res;j++){
                Work[j] += allocation[i][j];
                //printf("%d ",Work[j]);
            }
            //printf("need:");
            // for(int j=0;j<Num_Res;j++){
            //     //printf("%d ",Need[i][j]);
            // }
            //printf("\n");
            Finish[i] = 1;
            i=-1;
        }
    }
    
    num=0;
    //printf("Finish数组:  ");
    for(int j=0;j<Num_Cus;j++){
        if(Finish[j] == 1){
            num++;
        }
    }
    if(num == Num_Cus)
        flag = 1;    //系统处于安全状态
    else
        flag = 0;
    return flag;
}

int request_resources(int customer_num,int request[]){//用户请求资源
    int flag = 0;    //判断是否请求资源成功  0表示未成功,1表示成功;
    if(isless(request,Need[customer_num],Num_Res)){
        if(isless(request,ava,Num_Res)){
            for(int i=0;i<Num_Res;i++){     //假设分配
                ava[i] -= request[i];
                allocation[customer_num][i] += request[i];
                Need[customer_num][i] -= request[i]; 
            }
            if(!issafe()){                  //如果不安全,返回原状态,申请资源失败
                for(int i=0;i<Num_Res;i++){
                    ava[i] +=  request[i];
                    allocation[customer_num][i] -= request[i];
                    Need[customer_num][i] += request[i]; 
                }
                flag = 0;
                printf("客户%d没通过安全性算法,不批准获得资源!\n", customer_num);
            }
            else{  
                printf("客户%d已得到所需的资源\n", customer_num);
                printf("安全序列为 : < ");
                for(int i=0;i<Num_Cus;i++){
                    printf("%d ",arr[i]);
                }   
                printf(">\n");                   //申请资源成功,返回1
                flag = 1;
            }
        }
        else{
            printf("没有客户%d足够的资源 等着吧\n",customer_num);
        }
    }
    else{
        flag = 0;
        printf("你不诚心呀,%d号小伙子!\n",customer_num);
    }
    return flag;
}

int isrelease(int customer_num){
    int flag = 1;
    for(int i=0;i<Num_Res;i++){
        if(Need[customer_num][i]>0){
            flag=1;
            break;
        }
    }
    return flag;
}

int release_resources(int customer_num){//用户释放资源
    printf("客户%d开始释放资源\n", customer_num);
    int flag = 0;
    for(int i=0;i<Num_Res;i++){
        ava[i] += allocation[customer_num][i];
        allocation[customer_num][i] = 0;
    }  
    printf("客户%d已经释放全部资源\n", customer_num);
    flag = 1; 
    return flag;
}

void get_random(int customer_num,int request[]){
    for(int i=0;i<Num_Res;i++){
        request[i] = (rand()%(Need[customer_num][i]+1));
    }

}
//摘录
void usingthread(int customer_num)
{
	while (1)
	{
		int request[Num_Res];

        pthread_mutex_lock(&mutex);
		get_random(customer_num,request);
        pthread_mutex_unlock(&mutex);

        pthread_mutex_lock(&mutex); 
		printf("客户%d请求:", customer_num);
		for (int i = 0; i < Num_Res; i++)
			printf("%d ", request[i]);
		printf("\n");
        pthread_mutex_unlock(&mutex);

		pthread_mutex_lock(&mutex);    //上锁,开始请求资源
		while (request_resources(customer_num, request) == 0){ //若不满足银行家算法则等待
			pthread_cond_wait(&cond, &mutex);    //挂起等待直到条件满足  条件变量cond与互斥锁mutex一起用。
		}
		pthread_cond_broadcast(&cond);   //激活所有等待线程,区别signal(激活一个)
		pthread_mutex_unlock(&mutex);    //解锁
		//printf("客户%d已得到所需的资源\n", customer_num);
		sleep(1);
        if(isrelease(customer_num)){
            
            pthread_mutex_lock(&mutex);
            release_resources(customer_num);
            pthread_cond_broadcast(&cond);
			pthread_mutex_unlock(&mutex);
        }
		
		if (rand() % 2 == 0)
			break;
	}
	pthread_exit(NULL);
}


int main(int argc,char* argv[]){
    for(int i=1;i<argc;i++){
        ava[i] = atoi(argv[i]);
        //printf("%d ",ava[i]);
    }
    int request[Num_Res] = {1,0,2};
    int cus_num = 1;
    for(int i=0;i<Num_Cus;i++){
        for(int j=0;j<Num_Res;j++){
            Need[i][j] = max[i][j] - allocation[i][j];
        }
    }
    pthread_t tid[Num_Cus];
    pthread_attr_t attr[Num_Cus];

    pthread_mutex_init(&mutex, NULL);
	pthread_cond_init(&cond, NULL);
    for(int i=0;i<Num_Cus;i++){
        pthread_attr_init(&attr[i]);
    }
    for(int i=0;i<Num_Cus;i++){
        pthread_create(&tid[i], &attr[i], usingthread, i);        
    }
    for(int i=0;i<Num_Cus;i++){
        pthread_join(tid[i],NULL);  
    }
    return 0;
}

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值