一、实验目的
本实验要求学生编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁的发生。
二、实验题目
第一题:用银行家算法实现资源分配。要求:
(1) 设计一个3个并发进程共享10个同类资源的系统,进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。
(2) 设计用银行家算法和随机分配算法,实现资源分配的两个资源分配程序,应具有显示或打印各进程依次要求申请的资源数以及依次分配资源的情况。
(3) 确定一组各进程依次申请资源数的序列,在相同的情况下分别运行上述两种资源分配程序,观察运行结果。
第二题:用按序分配策略实现资源分配。要求:
(1) 设计一个3个进程共享10个资源的系统,进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。
(2) 设计用按序分配算法实现资源分配的资源分配程序,应具有显示或打印各进程依次要求申请的资源号以及依次分配资源地情况。
(3) 确定两组各进程依次要求申请的资源号,要求其中的一组中各进程按序地申请资源,另一组中各进程申请资源不受序号限制,分别运行上述设计的资源分配程序,观察运行结果。
三、数据结构
1)可利用资源向量available
具有m个元素的数组,available[j]=k表示系统中第j类资源有k个可用
2)最大需求矩阵max
n*m矩阵,max[i,j]=k表示进程i需要第j类资源的最大数目为k
3)分配矩阵allocation
n*m矩阵,allocation[i,j]=k表示进程i当前已占用的第j类资源的数目为k
4)需求矩阵need
n*m矩阵,need[i,j]=k表示进程还需要的第j类资源的数目为k
need[i,j] = max[i,j] - allocation[i,j]
5)进程pi的请求向量request[i]
具有m个元素的数组,说明进程pi对每类资源的请求数目
6)工作向量work 系统提供给进程继续运行所需各类资源数目
初值:work:=available
7)状态标志finish
具有n个元素的数据,表示进程是否可在有限时间内获得所有资源执行完,初值为fals
#include <stdio.h>
#include <stdlib.h>
/*----------------------常量定义--------------------*/
#define F 0
#define T 1
#define n 5 //进程数量
#define m 3 //资源种类数量
/*--------------------------------------------------*/
/*--------------------数据结构定义------------------*/
int Available[m]={3,3,2}; //可用资源
int Work[m]; //工作向量
i nt Finish[n]; //用以判断系统是否有足够资源分给相应进程
void Recycle(); //若进程运行完资源回收
int backDos(); //判断所有进程是否运行完,完后返回操作系统
/*--------------------------------------------------*/
/*-----------------------进程-----------------------*/
struct PCB
{
int flag; //状态标志,是否运行完
int Max[m]; //资源最大需求量
int Allocation[m]; //已分配资源
int Need[m]; //还需要的资源
int Request[m]; //请求资源量
}P[n];
/ *-----------------------函数声明--------------------*/
int tryAdminister(int num);//试分配
void safeCheck(int num); //安全性检查
void Print(); //状态输出
/*主函数(只需改变n、m和下面的初始数组便可形成新的进程量,资源量和状态)*/
int main()
{
int i, j, num;
int total[n][m]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
int have[n][m]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
int want[n][m]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};
for (i=0;i<n;i++) //初始化进程资源分配状态
for (j=0;j<m;j++)
{
P[i].flag = F;
P[i].Max[j]=total[i][j];
P[i].Allocation[j]=have[i][j];
P[i].Need[j]=want[i][j];
}
Print(); //状态输出
while (scanf("%d",&num)!=EOF)
{
printf("输入进程%d对这三类资源的需求向量(用空格隔开):\n",num);
scanf("%d %d %d",&P[num].Request[0],&P[num].Request[1],&P[num].Request[2]);
if (tryAdminister(num)==T)
safeCheck(num);
Recycle(); //资源回收
if(backDos()==T) //所有进程完则返回操作系统
return 0;
Print();
}
return 0;
}
/*--------------------------------------------------------------------*/
/*----------------------------试分配函数-----------------------------*/
int tryAdminister(int num) //试分配
{
int j;
for (j=0;j<m;j++)
if (P[num].Request[j]>P[num].Need[j])
{
printf("非法请求!\n\n");
return F;
}
else if (P[num].Request[j]>Available[j])
{
printf("%d号资源不够,无法分配,进程%d等待。\n\n",j,num);
return F;
}
for (j=0;j<m;j++)
{
Available[j] = Available[j] - P[num].Request[j];
P[num].Allocation[j] = P[num].Allocation[j] + P[num].Request[j];
P[num].Need[j] = P[num].Need[j] - P[num].Request[j];
}
return T;
}
}
k=0;
for (i=0;i<n;i++)
{
if (Finish[i]==F)
{
for (j=0;j<m;j++)
if (P[i].Need[j]>Work[j])break;
if (j==m) //如果分配成功
{
for (j=0;j<m;j++)
Work[j]=Work[j]+P[i].Allocation[j];
Finish[i]=T;
l[k]=i;
k++; //安全序列
i=-1; //就重新查找下一个可分配成功的进程
}
}
}
for (i=0;i<n;i++)
if (Finish[i]==F)
{
printf("分配不成功,系统将处于不安全状态.\n\n");
for (j=0;j<m;j++) //若分配不成功将进程num恢复到初始时刻状
{
Available[j] = Available[j] + P[num].Request[j];
P[num].Allocation[j] = P[num].Allocation[j] - P[num].Request[j];
P[num].Need[j] = P[num].Need[j] + P[num].Request[j];
}
break;
}
if (i==n)
{
printf("系统安全,一个进程安全序列如下:\n");
for (i=0;i<n;i++)
if (i!=n-1)
printf("P%d——>",l[i]);
else
printf("P%d\n\n",l[i]);
}
}
/*-------------------------------安全性检查函数-------------------------------*/
void safeCheck(int num)
{
int i,j;
int l[n],k; //安全序列
for (j=0;j<m;j++) //初始化工作向量
Work[j]=Available[j];
for (i=0;i<n;i++) //初始化判断向量
{
Finish[i]=F;
l[i]=0;
/*------------------------------------状态输出-----------------------------*/
void Print()
{
int i;
printf("此时资源分配情况:\n");
printf
("********************************************************************\n");
printf("\t最大需求\t已分配\t\t需要分配\t可用资源\n");
for (i=0;i<n;i++) //输出进程资源分配状态
{
printf("P%d\t%d %d %d\t\t",i,P[i].Max[0],P[i].Max[1],P[i].Max[2]);
printf("%d %d %d\t\t",P[i].Allocation[0],P[i].Allocation[1],P
[i].Allocation[2]);
printf("%d %d %d\t\t",P[i].Need[0],P[i].Need[1],P[i].Need[2]);
if (i==0)
printf("%d %d %d\n",Available[0],Available[1],Available[2]);
else printf("\n");
}
printf
("********************************************************************\n");
printf("输入下一时刻需要分配的进程号:\n");
}
/*-------------------------------资源回收--------------------------------*/
void Recycle()
{
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
if (P[i].Need[j]!=0)break;
if (j==m)
{
if (P[i].flag==F)
{
//若进程已得到所有资源并运行完则回收资源
printf("进程P%d已运行完;\n\n",i);
for (j=0;j<m;j++)
{
Available[j] = Available[j]+P[i].Allocation[j];
P[i].Allocation[j]=0;
}
P[i].flag=T;
}
}
}
}
/*-------------------------所有进程运行完就返回操作系统----------------------*/
int backDos()
{
int i;
for(i=0;i<n;i++)
if(P[i].flag!=T)return F;
printf("所有进程已经运行完,程序结束!\n");
return T;
}
第二篇:操作系统实验(模拟进程管理)
操作系统实验
————(1)模拟进程管理
专业:信息管理与信息系统
班级:信管082
姓名:温静
实验一 进程管理
1.目的和要求
通过实验理解进程的概念,进程的组成(PCB结构),进程的并发执行和操作系统进行进程管理的相关原语(主要是进程的创建、执行、撤消)。
2.实验内容
用C语言编程模拟进程管理,至少要有:创建新的进程;查看运行进程;换出某个进程;杀死运行进程以及进程之间通信等功能。
3.主体程序
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
struct PCB_type
{ int pid;
int priority;
int cputime;
int state;
int shumu=0,pid_l;
struct PCB_type neicun[20];
struct PCB_type hc[10];
int max=0;int number=0;
void create();
void run();
void huanchu();
void kill();
/* 创建新进程 */
void create()
{
if(shumu>=20) printf("\n内存已满,请先结束或换出进程\n"); {
}
else
{
}
/* 查看当前运行进程 */ void run()
{
}
/* 换出 */ void huanchu()
{
int k; printf("请输入要换出程序的程序名:"); scanf("%d",&k); for(int j=0;j<shumu;j++) { if(neicun[j].state==1) { hc[number].pid=neicun[j].pid; hc[number].state=neicun[j].state; int max=0; for(int i=0;i<shumu;i++) { } neicun[max].state=3; printf("当前运行进程程序名:\n%d",neicun[max].pid); printf("\n该进程的优先级:\n%d",neicun[max].priority); printf("\n该进程的运行时间:\n%d",neicun[max].cputime); printf("\n该进程的状态:\n%d",neicun[max].state); if((neicun[i].state==1)&&(neicun[i].priority>=neicun[max].priority)) max=i; shumu++; printf("\n请输入新进程的程序名\n"); scanf("%d",&neicun[shumu-1].pid); printf("\n请输入新进程的优先级\n"); scanf("%d",&neicun[shumu-1].priority); printf("\n请输入新进程的运行时间\n"); scanf("%d",&neicun[shumu-1].cputime); } printf("\n创建进程成功!\n"); printf("\n创建进程时令其状态为就绪\n"); neicun[shumu-1].state=2;
} hc[number].priority=neicun[j].priority; hc[number].cputime=neicun[j].cputime; number++; neicun[j].pid=0; neicun[j].state=0; neicun[j].priority=0; neicun[j].cputime=0; pid_1++; else printf("进程%d无法换出的pid:%d\n",j.neicun[j].pid); if(number!=0) for(int i=0;i<number;i++) { printf("当前运行进程程序名:\n%d",hc[i].pid);
printf("\n该进程的运行时间:\n%d",hc[i].cputime); printf("\n该进程的优先级:\n%d",hc[i].priority);
} } } printf("\n该进程的状态:\n%d",hc[i].state); PCB_type temp=neicun[0]; for(k=0;k<=shumu;k++) { } neicun[k].state=1; if(neicun[k].priority>temp.priority) tmpe=neicun[k];
/* 杀死进程 */ void kill()
{
neicun[max].pid=0;
neicun[max].priority=0; neicun[max].cputime=0; neicun[max].state=0; if(max==(shumu-1)) else{ for(int j=max+1;j<shumu;j++) { neicun[j-1].pid=neicun[j].pid; neicun[j-1].priority=neicun[j].priority; neicun[j-1].cputime=neicun[j].cputime; neicun[j-1].state=neicun[j].state; shumu--;
} } } shumu--; max=0; run();
/* int k=0;
}*/
int main() {
int n,a; n=1;
while(n==1) {
system("cls"); printf("\n**********************************************"); printf("\n* 进程演示系统 *"); printf("\n**********************************************"); printf("\n 1.创建新的进程 2.查看运行进程"); printf("\n 3.换出某个进程 4.杀死运行进程"); printf("\n 5.退出系统 "); printf("\n**********************************************"); printf("请输入要杀死程序的进程名:"); scanf("%d",&k); if(neicun[k].state=1) neicun[k].state=2; neicun[k].cputime=0; neicun[k].pid=0; neicun[k].priority=0; neicun[k].state=0; shumu--; else{ } printf("进程%d已被杀死!,k"); for(int j=k+1;j<shumu;j++) { } neicun[j-1].pid=neicun[j].pid; neicun[j-1].priority=neicun[j].priority; neicun[j-1].cputime=neicun[j].cputime; neicun[j-1].state=neicun[j].state; if(k==(shumu-1)) shumu--;
printf("\n请选择(1~5):"); scanf("%d",&a); switch(a) { case 1: create( ); printf("\npress anykey to go on~"); } } getch(); break; case 2 : run(); printf("\npress anykey to go on~"); getch(); break; case 3 : huanchu(); printf("\npress anykey to go on~"); getch(); break; case 4 : kill(); printf("\npress anykey to go on~"); getch(); break; case 5 : exit(0); default: n=0; break; }
5.感想与心得体会
做了两周的实验,问了很多同学,可程序还是有很多问题。通过这次实验,我发现了自己在模拟进程调度和模拟程序换出这两块地方有很多东西都没有学好,自己还有很多的不足。以后还应多看看书,加深自己的知识储备。希望下次试验会比这次熟练多些。
最后,真的要感谢徐老师耐心、细心的讲解。