实验要求
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] = 0;
for (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;
}
实验结果截图