银行家算法(c语言/多线程/Linux环境)

银行家算法(c语言/多线程/Linux环境)

编译命令:

gcc bank-algorithm.c -o bank-algorithm -lpthread

运行命令示例:

./bank-algorithm 5 5 5

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define resourceTypeQuan 3
#define processQuan 5

int i = 0;//Switch on C99 mode or we cannot initialize variable in for loop
int j = 0;
pthread_mutex_t mutex;//mutex lock for access to global variable

int initResourceVector [resourceTypeQuan];
//available, max, allocation, need
int availResourceVector [resourceTypeQuan];
int allocMatrix [processQuan][resourceTypeQuan] = {{1,1,0},{1,3,0},{0,0,2},{0,1,1},{0,2,0}};
int maxMatrix [processQuan][resourceTypeQuan] = {{5,5,5},{3,3,6},{3,5,3},{7,1,4},{7,2,2}};
int needMatrix [processQuan][resourceTypeQuan];

int requestResource(int processID,int requestVector[]);
int releaseResource(int processID,int releaseVector[]);
int ifGreaterThanNeed(int processID,int requestVector[]);
int ifEnoughToRelease(int processID,int releaseVector[]);
int ifInSafeMode();
int ifEnoughToAlloc();
void printNeedMatrix();
void printAllocMatrix();
void printAvailable();
void printReqOrRelVector(int vec[]);
void *customer(void* customerID);

int main(int argc, char const *argv[])
{
	if(argc != resourceTypeQuan + 1)
	{
		printf("Quantity of parameter is not correct.\n");
		return -1;
	}
	for(i = 0; i < resourceTypeQuan; i++)
	{
		initResourceVector[i] = atoi(argv[i+1]);//argv[0] is name of program
		availResourceVector[i] = initResourceVector[i];
	}

	//initialize needMatrix
	for (i = 0; i < processQuan; ++i)
	{
		for (j = 0; j < resourceTypeQuan; ++j)
		{
			needMatrix[i][j] = maxMatrix[i][j] - allocMatrix[i][j];
		}
	}

	printf("Available resources vector is:\n");
	printAvailable();

	printf("Initial allocation matrix is:\n");
	printAllocMatrix();

	printf("Initial need matrix is:\n");
	printNeedMatrix();

	pthread_mutex_init(&mutex,NULL);//declared at head of code
	pthread_attr_t attrDefault;
	pthread_attr_init(&attrDefault);
	pthread_t *tid = malloc(sizeof(pthread_t) * processQuan);
	int *pid = malloc(sizeof(int) * processQuan);//customer's ID, for banker's algorithm, not pthread
	//initialize pid and create threads
	for(i = 0; i < processQuan; i++)
	{
		*(pid + i) = i;
		pthread_create((tid+i), &attrDefault, customer, (pid+i));
	}
	//join threads
	for(i = 0; i < processQuan; i++)
	{
		pthread_join(*(tid+i),NULL);
	}
	return 0;
}

void *customer(void* customerID)
{
	int processID = *(int*)customerID;

	while(1)
	{
		//request random number of resources
		sleep(1);
		int requestVector[resourceTypeQuan];

		//Because i is global variable, we should lock from here
		//lock mutex for accessing global variable and printf
		pthread_mutex_lock(&mutex);
		//initialize requestVector
		for(i = 0; i < resourceTypeQuan; i++)
		{
			if(needMatrix[processID][i] != 0)
			{
				requestVector[i] = rand() % needMatrix[processID][i];
			}
			else
			{
				requestVector[i] = 0;
			}
		}


		printf("Customer %d is trying to request resources:\n",processID);
		printReqOrRelVector(requestVector);
		//requestResource() will still return -1 when it fail and return 0 when succeed in allocate, like textbook says
		//altough I put the error message output part in the requestResource function
		requestResource(processID,requestVector);
		//unlock
		pthread_mutex_unlock(&mutex);
	
		//release random number of resources		
		sleep(1);
		int releaseVector[resourceTypeQuan];
		//Because i is global variable, we should lock from here
		//lock mutex for accessing global variable and printf
		pthread_mutex_lock(&mutex);
		//initialize releaseVector
		for(i = 0; i < resourceTypeQuan; i++)
		{
			if(allocMatrix[processID][i] != 0)
			{
				releaseVector[i] = rand() % allocMatrix[processID][i];
			}
			else
			{
				releaseVector[i] = 0;
			}
		}
		printf("Customer %d is trying to release resources:\n",processID);
		printReqOrRelVector(releaseVector);
		//releaseResource() will still return -1 when it fail and return 0 when succeed in allocate, like textbook says
		//altough I put the error message output part in the releaseResource function
		releaseResource(processID,releaseVector);
		//unlock
		pthread_mutex_unlock(&mutex);
	}
}

int requestResource(int processID,int requestVector[])
{
	//whether request number of resources is greater than needed
	if (ifGreaterThanNeed(processID,requestVector) == -1)
	{
		printf("requested resources is bigger than needed.\n");
		return -1;
	}
	printf("Requested resources are not more than needed.\nPretend to allocate...\n");

	//whether request number of resources is greater than needed
	if(ifEnoughToAlloc(requestVector) == -1)
	{
		printf("There is not enough resources for this process.\n");
		return -1;
	}

	//pretend allocated
	for (i = 0; i < resourceTypeQuan; ++i)
	{
		needMatrix[processID][i] -= requestVector[i];
		allocMatrix[processID][i] += requestVector[i];
		availResourceVector[i] -= requestVector[i];
	}
	printf("Checking if it is still safe...\n");
	
	//check if still in safe status
	if (ifInSafeMode() == 0)
	{
		printf("Safe. Allocated successfully.\nNow available resources vector is:\n");
		printAvailable();
		printf("Now allocated matrix is:\n");
		printAllocMatrix();
		printf("Now need matrix is:\n");
		printNeedMatrix();
		return 0;
	}
	else
	{
		printf("It is not safe. Rolling back.\n");
		for (i = 0; i < resourceTypeQuan; ++i)
		{
			needMatrix[processID][i] += requestVector[i];
			allocMatrix[processID][i] -= requestVector[i];
			availResourceVector[i] += requestVector[i];
		}
		printf("Rolled back successfully.\n");
		return -1;
	}
}

int releaseResource(int processID,int releaseVector[])
{
	if(ifEnoughToRelease(processID,releaseVector) == -1)
	{
		printf("The process do not own enough resources to release.\n");
		return -1;
	}

	//enough to release
	for(i = 0; i < resourceTypeQuan; i++)
	{
		allocMatrix[processID][i] -= releaseVector[i];
		needMatrix[processID][i] += releaseVector[i];
		availResourceVector[i] += releaseVector[i];
	}
	printf("Release successfully.\nNow available resources vector is:\n");
	printAvailable();
	printf("Now allocated matrix is:\n");
	printAllocMatrix();
	printf("Now need matrix is:\n");
	printNeedMatrix();
	return 0;
}

int ifEnoughToRelease(int processID,int releaseVector[])
{
	for (i = 0; i < resourceTypeQuan; ++i)
	{
		if (releaseVector[i] <= allocMatrix[processID][i])
		{
			continue;
		}
		else
		{
			return -1;
		}
	}
	return 0;
}
int ifGreaterThanNeed(int processID,int requestVector[])
{
	for (i = 0; i < resourceTypeQuan; ++i)
	{
		if (requestVector[i] <= needMatrix[processID][i])
		{
			continue;
		}
		else
		{
			return -1;
		}
	}
	return 0;
}

int ifEnoughToAlloc(int requestVector[])
{
	//first element of requestVector is processID
	for (i = 0; i < resourceTypeQuan; ++i)
	{
		if (requestVector[i] <= availResourceVector[i])
		{
			continue;
		}
		else
		{
			return -1;
		}
	}
	return 0;
}

void printNeedMatrix()
{
	for (i = 0; i < processQuan; ++i)
	{
		printf("{ ");
		for (j = 0; j < resourceTypeQuan; ++j)
		{
			printf("%d, ", needMatrix[i][j]);
		}
		printf("}\n");
	}
	return;
}

void printAllocMatrix()
{
	for (i = 0; i < processQuan; ++i)
	{
		printf("{ ");
		for (j = 0; j < resourceTypeQuan; ++j)
		{
			printf("%d, ", allocMatrix[i][j]);
		}
		printf("}\n");
	}
	return;
}

void printAvailable()
{
	for (i = 0; i < resourceTypeQuan; ++i)
	{
		printf("%d, ",availResourceVector[i]);
	}
	printf("\n");
	return;
}

void printReqOrRelVector(int vec[])
{
	for (i = 0; i < resourceTypeQuan; ++i)
	{
		printf("%d, ",vec[i]);
	}
	printf("\n");
	return;
}
int ifInSafeMode()
{
	int ifFinish[processQuan] = {0};//there is no bool type in old C
	int work[resourceTypeQuan];//temporary available resources vector
	for(i = 0; i < resourceTypeQuan; i++)
	{
		work[i] = availResourceVector[i];
	}
	int k;
	for(i = 0; i < processQuan; i++)
	{
		if (ifFinish[i] == 0)
		{
			for(j = 0; j < resourceTypeQuan; j++)
			{
				if(needMatrix[i][j] <= work[j])
				{
					if(j == resourceTypeQuan - 1)//means we checked whole vector, so this process can execute
					{
						ifFinish[i] = 1;
						for (k = 0; k < resourceTypeQuan; ++k)
						{
							work[k] += allocMatrix[i][k];
							//execute and release resources
						}
						//if we break here, it will not check all process, so we should reset i to let it check from beginning
						//If we cannot find any runnable process from beginning to the end in i loop, we can determine that
						//there is no any runnable process, but we cannot know if we do not reset i.
						i = -1;//at the end of this loop, i++, so -1++ = 0
						break;//in loop j, break to loop i and check next runnable process
					}
					else//not finished checking all resource, but this kind resources is enough
					{
						continue;
					}
				}
				else//resources not enough, break to loop i for next process
				{
					//because there is no change happened, so we do not need to reset i in this condition.
					break;
				}
			}
		}
		else
		{
			continue;
		}
	}
	//there are two condition if we finish loop i
	//1. there is no process can run in this condition.
	//2. all processes are runned, which means it is in safe status.
	for(i = 0; i < processQuan; i++)
	{
		if (ifFinish[i] == 0)
		{
			//not all processes are runned, so it is condition 1.
			return -1;
		}
		else
		{
			continue;
		}
	}
	//finished loop, so it is condition 2
	return 0;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值