操作系统之多线程实现银行家算法

    技术2026-04-08  5

    实验要求 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; }

    实验结果截图

    Processed: 0.014, SQL: 9