天天看點

多線程模拟銀行家算法

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUMBER_OF_CUSTOMERS 5
#define NUMBER_OF_RESOURCES 3
pthread_mutex_t mutex;
int f_num = 0;
int s_num = 0;
int t_num = 0;
int mcount = 0;
int available[NUMBER_OF_RESOURCES];
int maximum[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
int allocation[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
int need[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];
pthread_t tids[NUMBER_OF_CUSTOMERS];

int create_rand(int start, int end){
	return start + (int)(rand() / (RAND_MAX + 1.0) * (end - start));
}
void print(){
	int i,j;
	printf("available:\n");
	for (i=0; i<NUMBER_OF_RESOURCES; i++){
		printf("%d ", available[i] );
	}
	printf("\nmaximum:\n");
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		for (j=0; j<NUMBER_OF_RESOURCES; j++){
			printf("%d ", maximum[i][j]);
		}
		printf("\n");
	}
	printf("allocation:\n");
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		for (j=0; j<NUMBER_OF_RESOURCES; j++){
			printf("%d ", allocation[i][j]);
		}
		printf("\n");
	}
	printf("need:\n");
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		for (j=0; j<NUMBER_OF_RESOURCES; j++){
			printf("%d ", need[i][j]);
		}
		printf("\n");
	}
}
void init(){
	available[0] = f_num;
	available[1] = s_num;
	available[2] = t_num;
	int i, j;
	pthread_mutex_init(&mutex, NULL);
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		for (j=0; j<NUMBER_OF_RESOURCES; j++){
			maximum[i][j] = create_rand(0, available[j]+1);
			allocation[i][j] = 0;
			need[i][j] = maximum[i][j] - allocation[i][j];
		}
	}
	for (i=0; i<NUMBER_OF_RESOURCES; i++){
		int sum = 0;
		for (j=0; j<NUMBER_OF_CUSTOMERS; j++){
			sum += allocation[j][i];

		}
		available[i] -= sum;
	}
	print();
}
//check safe return 1 if safe else return 0
int safe(){
	int work[NUMBER_OF_RESOURCES];
	int i;
	for (i=0; i<NUMBER_OF_RESOURCES; i++){
		work[i] = available[i];
	}
	//0 for false, 1 for true
	int finish[NUMBER_OF_CUSTOMERS];
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		finish[i] = 0;
	}
	while (1){
		int flag = 1;
		for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
			if (finish[i] == 0 && need[i][0] <= work[0] && need[i][1] <= work[1] && need[i][2] <= work[2]){
				work[0] += need[i][0];
				work[1] += need[i][1];
				work[2] += need[i][2];
				finish[i] = 1;
				flag = 0;
			}
		}
		if (flag == 1){
			break;
		}
	}
	int flag = 1;
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		if (finish[i] == 0){
			flag = 0;
		}
	}
	if (flag == 1){
		return 1;
	} else {
		return 0;
	}
}
void *req(int num){
	while (1){
		int request[NUMBER_OF_RESOURCES];
		int i;
		pthread_mutex_lock(&mutex);
		for (i=0; i<NUMBER_OF_RESOURCES; i++){
			request[i] = create_rand(0, need[num][i]+1);
			//request[i] = need[num][i];
		}
		if (request[0] == 0 && request[1] == 0 && request[2] == 0){
			pthread_mutex_unlock(&mutex);
			continue;
		}
		printf("%d request:%d %d %d", num+1, request[0], request[1], request[2]);
		if (request[0] <= available[0] && request[1] <= available[1] && request[2] <= available[2]){
			available[0] -= request[0];
			available[1] -= request[1];
			available[2] -= request[2];
			allocation[num][0] += request[0];
			allocation[num][1] += request[1];
			allocation[num][2] += request[2];
			need[num][0] -= request[0];
			need[num][1] -= request[1];
			need[num][2] -= request[2];
			if (need[num][0] == 0 && need[num][1] == 0 && need[num][2] == 0){
				available[0] += allocation[num][0];
				available[1] += allocation[num][1];
				available[2] += allocation[num][2];
				mcount++;
				if (mcount == NUMBER_OF_CUSTOMERS){
					printf(" complete\n" );
					print();
					exit(0);
				}
				//return;
			}
			if (safe() == 0){
				available[0] += request[0];
				available[1] += request[1];
				available[2] += request[2];
				allocation[num][0] -= request[0];
				allocation[num][1] -= request[1];
				allocation[num][2] -= request[2];
				need[num][0] += request[0];
				need[num][1] += request[1];
				need[num][2] += request[2];
				printf(" unsafe ");
			} else {
				printf(" safe ");
			}
			printf("available: %d %d %d ", available[0], available[1], available[2]);
			printf(" need: %d %d %d\n", need[num][0], need[num][1], need[num][2]);
			//printf("safe?%d\n", safe());
		} else {
			printf("\n");
		}
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
int main(int argc, char *argv[]){
	if (argc != 4){
		fprintf(stderr, "please input 3 param");
		return -1;
	}
	f_num = atoi(argv[1]);
	s_num = atoi(argv[2]);
	t_num = atoi(argv[3]);
	if (f_num < 0 || s_num < 0 || t_num < 0){
		fprintf(stderr, "param should not be negative");
		return -1;
	}
	srand((unsigned)time(NULL));
	init();
	if (safe() == 0){
		printf("unsafe at first\n");
		return 0;
	}
	int i;
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		pthread_t tid;
		tids[i] = tid;
		pthread_attr_t attr;
		pthread_attr_init(&attr);
		pthread_create(&tid, &attr, req, i);
	}
	for (i=0; i<NUMBER_OF_CUSTOMERS; i++){
		pthread_join(tids[i], NULL);
	}
	return 0;
}
           

gcc bankers.c -o b.out -lpthread

./b.out 10 7 5

誰用誰知道

繼續閱讀