多线程实现银行家算法

实验要求
1.测试数据随机产生。不可手工输入;
2.线程所需的全部资源一次全部给予
3.线程释放资源时分多次释放,一次释放一种所有资源。
提出第2和第3点要求的原因是模拟进程的调度不容易,所以以多个线程请求资源来模拟一个进程多次请求资源

程序流程图
在这里插入图片描述
实验心得
第一次使用条件变量,对条件变量cond的使用更加熟悉了。
为了防止出现临界区内因条件不足不程序无法继续运行下去,而又因为是在临界区,所以代码运行的互斥的,所以条件就永远不能满足导致程序一直无法运行下去。所以出现了条件变量cond。
pthread_cond_wait(&cond, &mutex);挂起等待条件cond的调用线程,释放锁,以便其他线程使用。
pthread_cond_broadcast(&cond);恢复执行先前因在条件cond上执行pthread_cond_wait而挂起的那几个线程。

实验代码

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>

#define Maxpronum 1000
#define m 4 /*一共有4种资源*/

int pronum = 0; //当前运行线程数

int threadFinished[Maxpronum];
int mark[Maxpronum];
int Allocation[Maxpronum][m];
int Need[Maxpronum][m];
int Avaliable[m];
int Max[Maxpronum][m];

pthread_mutex_t mutex;
pthread_cond_t cond;

void init() //数据初始化
{
	for (int i = 0; i < Maxpronum; i++)	
	{
		mark[i] = 0for (int j = 0; j < m; j++)
		{
			Allocation[i][j] = 0;
			Need[i][j] = 0;
			Max[i][j] = 0;
		}
	}
	for (int i = 0; i < m; i++)
	{
		Avaliable[i] = 100;
	}
}
int safe(int id) //安全性算法
{
	int Work[4];
	int Finish[Maxpronum];
	int safecount = 0;
	int count;
	int n = Maxpronum;
	int threadSafeSequence[Maxpronum];
	for (int i = 0; i < m; i++)
		Work[i] = Avaliable[i];
	for (int i = 0; i < m; i++)
		Finish[i] = 0;
	for (int k = 0; k < n; k++) //尝试得到安全序列
	{
		for (int i = 0; i < n; i++)
		{
			count = 0;
			for (int j = 0; j < m; j++)
			{
				if (Need[i][j] <= Work[j])
				count++;
			}
			if (count == m)
			{
				for (int j = 0; j < m; j++)
				{
					Work[j] = Work[j] + Allocation[i][j];
				}
				if (mark[i] == 1 && Finish[i] == 0)
				{
					Finish[i] = 1;		
					threadSafeSequence[safecount++] = i;
				}
			}
		}
	}
	count = 0;
	for (int i = 0; i < n; i++)
	{
		if (mark[i] == 1)
		count++;
	}
	if (count == pronum)
	{
		printf("安全序列为:");
		for (int i = 0; i < safecount; i++)
			printf(" %d", threadSafeSequence[i]);
		printf("\n");
		return 1;
	}
	else
	{
		return 0;
	}
}

int Banker(int id, int Request[]) //银资源分配算法
{
	for (int i = 0; i < m; i++)
	{
		if (Request[i] > Avaliable[i])
		{
			printf("线程%d所需的资源不足,等待!\n", id);
			return 0;
		}
	}
	for (int i = 0; i < m; i++)
	{
		if (Request[i] > Need[id][i] + Allocation[id][i])
		{
			printf("线程%d对资源的申请量大于它说明的最大值\n", id);
			return 0;
		}
	}
	for (int i = 0; i < m; i++) //尝试分配资源
	{
		Avaliable[i] = Avaliable[i] - Request[i];
		Allocation[id][i] = Allocation[id][i] + Request[i];
		Need[id][i] = Need[id][i] - Request[i];
	}
	mark[id] = 1;
	pronum++;
	if (!safe(id)) //分配后不存在安全序列则回收资源
	{
		for (int i = 0; i < m; i++)
		{
			Avaliable[i] = Avaliable[i] + Request[i];
			Allocation[id][i] = Allocation[id][i] - Request[i];
			Need[id][i] = Need[id][i] + Request[i];
		}
		mark[id] = 0;
		pronum--;
		printf("线程%d没通过安全性算法,不批准获得资源!\n", id);
		return 0; /*不安全*/
	}
	return 1; /*安全*/
}

void *threadprocess(void *arg)
{
	while (1)
	{
		int id = *(int *)arg;
		int Request[m];
		for (int i = 0; i < m; i++)
		{
			Request[i] = Need[id][i] = Max[id][i] = rand() % 30; //随机生成需要的资源数
		}
		printf("线程%d请求:", id);
		for (int i = 0; i < m; i++)
			printf("%d ", Request[i]);
		printf("\n");
		pthread_mutex_lock(&mutex);
		while (Banker(id, Request) == 0) //若不满足银行家算法则等待
		{
			pthread_cond_wait(&cond, &mutex);
		}
		for (int i = 0; i < m; i++)
		{
			Need[id][i] = 0;
		}
		pthread_cond_broadcast(&cond);
		pthread_mutex_unlock(&mutex);

		printf("线程%d已得到全部所需的资源\n", id);
		sleep(1);
		printf("线程%d开始释放资源\n", id);
		for (int i = 0; i < m; i++) //每隔一段时间释放一种资源
		{
			sleep(rand() % 3);
			pthread_mutex_lock(&mutex);
			Avaliable[i] = Avaliable[i] + Request[i];
			Max[id][i] = 0;
			Allocation[id][i] = 0;
			if (i == m - 1)
			{
				mark[id] = 0;
				pronum--;
			}
			pthread_cond_broadcast(&cond);
			pthread_mutex_unlock(&mutex);
		}
		printf("线程%d已经释放全部资源\n", id);
		if (rand() % 2 == 0)
			break;
	}
	pthread_exit(NULL);
}
int main()
{
	init();
	pthread_t tid[Maxpronum];
	pthread_mutex_init(&mutex, NULL);
	pthread_cond_init(&cond, NULL);
	int M[Maxpronum];
	int i = 0;
	while (1)
	{
		if (rand() % 2 == 0)
		{
			while (mark[i] == 1)
			i = i + 1;
			M[i] = i;
			pthread_create(&tid[i], NULL, threadprocess, (void *)&M[i]);
			sleep(rand() % 3);
		}
		i = i + 1;
		if (i == Maxpronum - 1)
			i = 0;
	}
	for (int i = 0; i < Maxpronum; i++)
	pthread_join(tid[i], NULL);
	return 0;
}

实验结果截图
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章