C++实现死锁的监测

C++实现死锁的监测
C++实现死锁的监测

C++实现死锁的监测

#include"iostream"

#include"fstream"

#include"vector"

#include"windows.h"

using namespace std;

vector have[500]; //每个进程已经有的资源

vector want[500]; //各个进程想要的资源

int pro_size; //进程数

int res_size; //资源种类数

int res[500]; //每类资源的个数

int work[500]; //当前可用资源数

vector Deadlock;

bool* visited;

bool* Dead_res;

void DeadlockChain(int beg){

visited[beg] = true;

cout << "Process:" << beg << endl;

for (int i = 0; i < want[beg].size(); i++)

for (int j = 0; j < Deadlock.size(); j++)

for (int k = 0; k < have[Deadlock[j]].size(); k++)

if (have[Deadlock[j]][k] == want[beg][i]){

Dead_res[want[beg][i]] = true;

if (!visited[j])

DeadlockChain(j);

}

for (int t = 0; t < have[beg].size(); t++)

for (int j = 0; j < Deadlock.size(); j++)

for (int k = 0; k < want[Deadlock[j]].size(); k++) if (want[Deadlock[j]][k] == have[beg][t]){

Dead_res[have[beg][t]] = true; if (!visited[j])

DeadlockChain(j);

}

}

void read_data(){

ifstream in;

in.open("D://a.txt");

if (!in)

cout << "FILE OPEN FAILED!" << endl;

memset(res, 0, 500);

memset(work, 0, 500);

//**********************************************

//Read res

in >> res_size;

if (res_size > 500){

cout << "Number of res should be small than 500" << endl;

exit(-1);

}

for (int i = 0; i < res_size; i++){

int temp;

in >> temp;

if (temp < 0){

cout << "Illegal No. of res!" << endl;

cout << "Please check your input data!" << endl;

exit(-1);

}

res[i] = work[i] = temp;

}

//************************************************

//Read pro

in >> pro_size;

if (pro_size > 500){

cout << "Number of pro should be small than 500" << endl;

exit(-1);

}

for (int k = 0; k < pro_size; k++){

int num;

in >> num;

int have_size;

in >> have_size;

for (int i = 0; i < have_size; i++){

int temp;

in >> temp;

if (temp >= res_size){

cout << "illegal res No.!" << endl;

cout << "Please check your input data!" << endl;

exit(-1);

}

work[temp]--;

if (work[temp] < 0){

cout << "Impossible res dispatch situation!" << endl;

cout << "Please check your input data!" << endl;

exit(-1);

}

have[num].push_back(temp);

}

//-------------------------------------------------------- int want_size;

in >> want_size;

for (int j = 0; j < want_size; j++){

int temp;

in >> temp;

if (temp >= res_size){

cout << "illegal res No.!" << endl;

cout << "Please check your input data!" << endl;

exit(-1);

}

want[num].push_back(temp);

}

}

}

//**********************************************************

void Draw(){

HWND hWnd = FindWindow("ConsoleWindowClass", NULL);

HDC hDc = GetDC(hWnd);

HPEN hPen1 = CreatePen(PS_SOLID, 2, 0x000000FF);//生成红线

HPEN hPen2 = CreatePen(PS_SOLID, 2, 0x0000FF00);//生成蓝线

SelectObject(hDc, hPen1);

int i;

for (i = 0; i < res_size; i++){

Ellipse(hDc, i * 100, 0, i * 100 + 50, 50);

char s[5];

s[0] = 'R';

s[1] = i + 48;

s[2] = '/0';

TextOut(hDc, i * 100 + 20, 25, s, 2);

for (int k = 0; k < res[i]; k++)

Ellipse(hDc, i * 100 + k * 10 + 5, 10, i * 100 + k * 10 + 15, 20);

}

for (i = 0; i < pro_size; i++){

Rectangle(hDc, i * 100, 100, i * 100 + 50, 150);

char s[5];

s[0] = 'P';

s[1] = i + 48;

s[2] = '/0';

TextOut(hDc, i * 100 + 20, 125, s, 2);

}

for (i = 0; i < 10; i++)

cout << endl;

for (i = 0; i < pro_size; i++)

for (int k = 0; k < res_size; k++){

int cnt = 5;

int j;

for (j = 0; j < have[i].size(); j++){

if (have[i][j] == k){

SelectObject(hDc, hPen2);

MoveToEx(hDc, i * 100 + cnt, 100, NULL);

LineTo(hDc, k * 100 + cnt, 50);

cnt += 10;

}

cnt = 5;

for (j = 0; j < want[i].size(); j++){

if (want[i][j] == k){

SelectObject(hDc, hPen1);

MoveToEx(hDc, i * 100 + 50 + cnt, 100, NULL);

LineTo(hDc, k * 100 + cnt, 50);

cnt -= 10;

}

}

}

}

//**********************************************************

void ers(int i){

system("pause");

HWND hWnd = FindWindow("ConsoleWindowClass", NULL);

HDC hDc = GetDC(hWnd);

HPEN hPen = CreatePen(PS_SOLID, 2, 0x00000000);

SelectObject(hDc, hPen);

for (int k = 0; k < res_size; k++){

int cnt = 5;

int j;

for (j = 0; j < have[i].size(); j++){

if (have[i][j] == k){

MoveToEx(hDc, i * 100 + cnt, 100, NULL);

LineTo(hDc, k * 100 + cnt, 50);

cnt += 10;

}

}

cnt = 5;

for (j = 0; j < want[i].size(); j++){

if (want[i][j] == k){

MoveToEx(hDc, i * 100 + 50 + cnt, 100, NULL);

LineTo(hDc, k * 100 + cnt, 50);

cnt -= 10;

}

}

}

}

//**********************************************************

void predigest(){

Draw();

bool finish[500]; //记录进程是否完成

for (int index = 0; index < pro_size; index++){

if (want[index].size() != 0){

finish[index] = false;

else{

finish[index] = true;

ers(index);

for (int i = 0; i < have[index].size(); i++)

work[have[index][i]]++;

} //此时就可以回收资源

}

bool flag;

do{

flag = false;

for (int i = 0; i < pro_size; i++)

if (!finish[i]){

int temp[500];

memset(temp, 0, 500);

for (int k = 0; k < want[i].size(); k++){

temp[want[i][k]]++;

}

bool ok = true;

for (int j = 0; j < res_size; j++)

if (temp[j] > work[j]){

ok = false;

break;

}//可以分配?

if (ok){

ers(i);

for (int t = 0; t < have[i].size(); t++){

work[have[i][t]]++;

} //回收资源

have[i].clear();

finish[i] = true;

flag = true;

}

}

} while (flag);

for (int i = 0; i < pro_size; i++)

if (finish[i] == false)

Deadlock.push_back(i);

if (Deadlock.size() != 0){

cout << "DeadLock has happened!" << endl << endl;

cout << "The processes & resources related to the deadlock is: " << endl;

visited = new bool[Deadlock.size() + 5]; //use to id wheather the pro is visited DFS

memset(visited, 0, Deadlock.size() + 5);

Dead_res = new bool[res_size + 5];

for (int i = 0; i < Deadlock.size(); i++){

if (!visited[i]){

memset(Dead_res, 0, res_size + 5);

DeadlockChain(i);

cout << "Resource: ";

for (int j = 0; j < res_size; j++)

if (Dead_res[j])

cout << j << " ";

}

cout << endl;

}

}

else

cout << "All process had execued!" << endl; }

int main()

{

read_data();

predigest();

return 0;

}

操作系统实验报告利用银行家算法避免死锁

计算机操作系统实验报告 题目利用银行家算法避免死锁 一、实验目的: 1、加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。 2、要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用银行家算法,有效的防止和避免死锁的发生。 二、实验内容: 用银行家算法实现资源分配: 设计五个进程{p0,p1,p2,p3,p4}共享三类资源{A,B,C}的系统,例如,{A,B,C}的资源数量分别为10,5,7。进程可动态地申请资源和释放资源,系统按进程的申请动态地分配资源,要求程序具有显示和打印各进程的某一个时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。 三、问题分析与设计: 1、算法思路: 先对用户提出的请求进行合法性检查,即检查请求是否大于需要的,是否大于可利用的。若请求合法,则进行预分配,对分配后的状态调用安全性算法进行检查。若安全,则分配;若不安全,则拒绝申请,恢复到原来的状态,拒绝申请。 2、银行家算法步骤: (1)如果Requesti<or =Need,则转向步骤(2);否则,认为出错,因

为它所需要的资源数已超过它所宣布的最大值。 (2)如果Request<or=Available,则转向步骤(3);否则,表示系统中尚无足够的资源,进程必须等待。 (3)系统试探把要求的资源分配给进程Pi,并修改下面数据结构中的数值: Available=Available-Request[i]; Allocation=Allocation+Request; Need=Need-Request; (4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。 3、安全性算法步骤: (1)设置两个向量 ①工作向量Work。它表示系统可提供进程继续运行所需要的各类资源数目,执行安全算法开始时,Work=Allocation; ②布尔向量Finish。它表示系统是否有足够的资源分配给进程,使之运行完成,开始时先做Finish[i]=false,当有足够资源分配给进程时,令Finish[i]=true。 (2)从进程集合中找到一个能满足下述条件的进程: ①Finish[i]=false ②Need

操作系统精髓与设计原理-第6章 并发性_死锁和饥饿

第六章习题翻译 第一部分复习题 6.1给出可重用资源和可消费资源的例子。 答:可重用资源:处理器,I/O通道,主存和辅存,设备以及诸如文件,数据库和信号量之类的数据结构。 可消费资源:中断,信号,消息和I/O缓冲区中的信息。 6.2可能发生死锁所必须的三个条件是什么? 答:互斥,占有且等待,非抢占。 6.3产生死锁的第4个条件是什么? 答:循环等待。 6.4如何防止占有且等待的条件? 答:可以要求进程一次性地请求所有需要的资源,并且阻塞这个资源直到所有请求都同时满足。 6.5给出防止无抢占条件的两种方法。 答:第一种,如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占用的资源,如果有必要,可再次请求这些资源和另外的资源。 第二种,如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程,要求它释放资源。 6.6如何防止循环等待条件? 答:可以通过定义资源类型的线性顺序来预防。如果一个进程已经分配到了R类型的资源,那么它接下来请求的资源只能是那些排在R类型之后的资源类型。6.7死锁避免,检测和预防之间的区别是什么? 答:死锁预防是通过间接地限制三种死锁必要条件的至少一个或是直接地限制循环等待的发生来避免死锁的出现。死锁避免允许可能出现的必要条件发生,但是采取措施确保不会出现死锁的情况。而死锁检测允许资源的自由分配,采取周期性的措施来发现并处理可能存在的死锁情况。 第二部分习题 6.1写出图6.1(a)中死锁的四个条件。 解:互斥:同一时刻只有一辆车可以占有一个十字路口象限。占有且等待:没有车可以倒退;在十字路口的每辆车都要等待直到它前面的象限是空的。非抢占: 没有汽车被允许挤开其他车辆。循环等待: 每辆汽车都在等待一个此时已经被其他车占领的十字路口象限。 6.2按照6.1节中对图6.2中路径的描述,给出对图6.3中6种路径的简单描述。 解:1.Q 获得 B 和A, 然后释放 B 和 A. 当 P 重新开始执行的时候, 它将会能够获得两个资源。 2. Q 获得 B和A, P 执行而且阻塞在对 A的请求上. Q释放 B 和A。当 P 重新开始执行的时候,它将会能够获得两个资源。 3. Q 获得 B ,然后 P 获得和释放 A. Q 获得A然后释放 B 和 A. 当 P 重新开始行的时候,它将会能够获得 B。 4. P 获得A然后 Q 获得 B. P 释放 A. Q 获得A然后释放

实验二 链表操作实现

实验二链表操作实现 实验日期: 2017 年 3 月 16 日 实验目的及要求 1. 熟练掌握线性表的基本操作在链式存储上的实现; 2. 以线性表的各种操作(建立、插入、删除、遍历等)的实现为重点; 3. 掌握线性表的链式存储结构的定义和基本操作的实现; 4. 通过本实验加深对C语言的使用(特别是函数的参数调用、指针类型的应用)。 实验容 已知程序文件linklist.cpp已给出学生身高信息链表的类型定义和基本运算函数定义。 (1)链表类型定义 typedef struct { int xh; /*学号*/ float sg; /*身高*/ int sex; /*性别,0为男生,1为女生*/ } datatype; typedef struct node{ datatype data; /*数据域*/ struct node *next; /*指针域*/ } LinkNode, *LinkList; (2)带头结点的单链表的基本运算函数原型 LinkList initList();/*置一个空表(带头结点)*/ void createList_1(LinkList head);/*创建单链表*/ void createList_2(LinkList head);/* 创建单链表*/ void sort_xh(LinkList head);/*单链表排序*/ void reverse(LinkList head);/*对单链表进行结点倒置*/ void Error(char *s);/*自定义错误处理函数*/ void pntList(LinkList head);/*打印单链表*/ void save(LinkList head,char strname[]);/*保存单链表到文件*/

操作系统课程设计----模拟银行家算法避免死锁

模拟通过银行家算法避免死锁 一、银行家算法产生的背景及目的 1:在多道程序系统中,虽然借助于多个进程的并发执行来改善系统的利用率,提高系统的吞吐量,但可能发生一种危险—死锁。死锁就是多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵局状态时,如无外力作用,他们将无法再向前进行,如再把信号量作为同步工具时,多个Wait和Signal 操作顺序不当,会产生进程死锁。 然而产生死锁的必要条件有互斥条件,请求和保持条件,不剥夺条件和环路等待条件。在预防死锁的几种方法中,都施加了较强的限制条件,在避免死锁的方法中,所施加的条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统都处于安全状态,便可避免死锁。2:实验目的:让学生独立的使用编程语言编写和调试一个系统分配资源的简单模拟程序,了解死锁产生的原因及条件。采用银行家算法及时避免死锁的产生,进一步理解课堂上老师讲的相关知识点。银行家算法是从当前状态出发,逐个按安全序列检查各客户中谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。 二:银行家算法中的数据结构 1:可利用资源向量Available。这是一个含有m个元素的数组,其中的每个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态的改变。如果Available[j]=k,z 则表示系统中现有Rj类资源K 个。 2:最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=k,表示第i个进程需要第Rj 类资源的最大数目k个. 3: 分配矩阵Allocation,也是n*m的矩阵,若Allocation[i,j]=k,表示第i 个进程已分配Rj类资源的数目为k个。 4:需求矩阵Need。也是一个n*m的矩阵,Need[i,j]=k,表示第i个进程还需Rj类资源k个。 三、银行家算法及安全性算法 1:银行家算法 设Request[i]是进程Pi的请求向量,若Request[i][j]=k;表示进程需要j类资源k个。当Pi发出资源请求时,系统按下属步骤进行检查; (1)如果Request[i][j]<=Need[i][j];便转向步骤(2),否则认为出错,因为它 所需要的资源数已超过他所宣布的最大值。 (2)如果Request[i][j]<=Available[i][j],便转向步骤(3),否则认为尚无足 够资源,进程需等待。

死锁与饥饿

死锁与饥饿 第五章死锁与饥饿 学习指导: 死锁是操作系统的棘手问题,因为不存在处理 死锁的完美方法。从理论上来说,如果给定进程有关资源的命令序列,可以给出避免死锁的充分必要算法,尽管其开销很大(NP完全),但实际以序列形式给出的资源需求对于稍微复杂一点的程序都是不现实的。 本章介绍的预防、避免、检测与恢复策略,在大多数实际系统中并未采用,一方面因为开销,另一方面因为使用的方便性。 然而本章内容仍是重要的,尤其是死锁避免与 检测。包括安全状态与安全序列的定义和检查算

法、避免死锁的资源分配算法。读者应当认真区分死锁避免算法与死锁检测算法之间的本质差别,尽管这两个算法在结构上很相似,差别只在Need与Work的比较和Request与Work的比较。 饥饿与饿死反映了资源分配策略的不公平性, 应当从进程状态方面理解饥饿与死锁之间的差 习题解答: 1.下面关于死锁问题的叙述哪些是正确的,哪 些是错误的,说明原因。 (1)参与死锁的所有进程都占有资 源; (2)参与死锁的所有进程中至少有两 个进程占有资源; (3)死锁只发生在无关进程之间; (4)死锁可发生在任意进程之间。 答:说法(1)是错误的,应该是参与死锁的所 有进程都等待资源。如下图所示,参与进程 pl、p2、p3、p4,尽管p3、p4不占有资源,但 也卷入死锁。

说法(2)正确。参与死锁的进程至少有两个,设为p1,p2,pl占有资源r1而等待资源 r2 , p2占有资源r2而等待资源r1。说法(3) 错误。死锁也可能发生在相关进程之间,如 pl和p2也可能是相关进程。 说法(4)正确,死锁既可能发生在相关进程之间,也可能发生在无关进程之间。即死锁 可发生在任意进程之间。 2.试证明当每个资源类中仅有一个资源实 例时,资源分配图中的环路是死锁的充要条 件。 证明:已知必要条件成立,即发生死锁必存 在环路,下面只需证明充分条件,即在每类资源仅有一个实例的前提下,环路意味着死锁。 假定环路上共有k个进程(k 2),设这k个进

数据结构 单链表基本操作代码

实验一单链表 #include "stdio.h" #include "stdlib.h" typedef int ElemType; typedef struct LNode { ElemType data; struct LNode *next; }LNode,*LinkList; void creatLNode(LinkList &head) { int i,n; LNode *p; head=(LNode*)malloc(sizeof(LNode)); head->next=NULL; printf("请输入链表的元素个数:"); scanf("%d",&n); for(i=n;i>0;i--) { p=(LNode*)malloc(sizeof(LNode)); printf("第%d个元素:",i); scanf("%d",&p->data); p->next=head->next; head->next=p; } } void InsertLNode(LinkList &L) { LNode *p=L; int i,j=0,e; printf("请输入你要插入的位置(超过链表长度的默认插在最后!):"); scanf("%d",&i); printf("请输入你要插入的元素:"); scanf("%d",&e); while (p->next&&jnext; ++j; }

LNode *s; s=(LNode*)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; } int DeleteLNode(LinkList &L,int i,int &e) { LNode *p; p=L; LNode *q; int j=0; while (p->next&&jnext; ++j; } if(!(p->next)||j>i-1) { printf("删除位置不合理!\n"); return 0; } q=p->next; p->next=q->next; e=q->data; free(q); return e; } void DeleteCF(LinkList &L) { LNode *p,*s,*r; p=L->next; while(p!=NULL) { r=p; s=r->next; while(s!=NULL) { if(p->data==s->data) { r->next=s->next; s=s->next;

数据结构课程设计单链表操作汇总

《数据结构课程设计》报告 题目:单链表操作 专业:计算机科学与技术 班级: 单链表操作 针对带头结点的单循环链表,编写实现以下操作的算法函数。

实现要求: ⑴单链表建立函数create:先输入数据到一维数组A[M]中,然后根据一维 数组A[M]建立一个单循环链表,使链表中个元素的次序与A[M]中各元素的次序相同,要求该函数的时间复杂度为O(m); ⑵定位查找函数Locate:在所建立的单循环链表中查找并返回值为key的 第1个元素的结点指针;若找不到,则返回NULL; ⑶求出该链表中值最大和次大的元素值,要求该算法的时间复杂度为O(m), 最大和次大的元素值通过指针变量带回,函数不需要返回值; ⑷将链表中所有值比key(值key通过形参传入)小的结点作为值为key的结 点前驱,所有值比key大的结点作为值为key的结点后继,并尽量保持原有结点之间的顺序,要求该算法的时间复杂度为O(m); ⑸设计一个菜单,具有上述处理要求和退出系统功能。 ⒈本人完成的工作: 一、定义结构体:LNode 二、编写以下函数: (1)建立单循环链表 (2)建立定位查找函数 (3)求出链表中最大和次大值 (4)将链表中的值和输入的Key比较,小的作为key前驱结点,大的作为key 的后继结点 三、设计具有上述处理要求和退出系统菜单 ⒉所采用的数据结构:单链表 数据结构的定义: typedef struct Node //定义结点的结构体 { DataType data; //数据域 struct Node *next; //指针域

}LNode; //结点的类型 ⒊所设计的函数 (1)Create(void) LNode *Create(void) //建立单循环链表,链表头结点head作为返回值{ int i,j,n,A[M]; //建立数组A【M】 LNode *head,*p,*move; head=(LNode*)malloc(sizeof(LNode)); //创建空单循环链表head->next=head; move=head; printf("请输入数组元素的个数:"); //输入数组 scanf("%d",&n); printf("请输入数组:"); for(i=0;idata=A[j]; p->next=move->next; move->next=p; move=move->next; } return head; //返回头指针

操作系统实验报告-死锁的避免

操作系统实验报告-死锁的避免

操作系统实验(二)死锁的避免 1.实验内容 使用C++实现模拟随机算法和银行家算法 2.实验目的 (1)了解死锁的产生原因(随机算法) (2)理解死锁的解决办法(银行家算法) 3.实验题目 使用随机算法和银行家算法设计程序 4.程序流程图 主要过程流程图

银行家算法流程图

安全性算法流程图

5.程序代码和运行结果#include #include typedef struct { int A; int B; int C; }RES; #define false 0

#define true 1 //系统中所有进程数量 #define PNUMBER 3 //最大需求矩阵 RES Max[PNUMBER]; //已分配资源数矩阵 RES Allocation[PNUMBER]; //需求矩阵 RES Need[PNUMBER]; //可用资源向量 RES Available={0,0,0}; //安全序列 int safe[PNUMBER]; void setConfig() { int i=0,j=0; printf("================开始手动配置资源==================\n"); //可分配资源 printf("输入可分配资源\n"); scanf("%d%d%d",&Available.A,&Available.B,&Available.C); //最大需求矩阵MAX printf("输入最大需求矩阵%dx%d\n",PNUMBER,PNUMBER ); for (i=0;i

实验二单链表基本操作技巧

实验二单链表基本操作 一实验目的 1.学会定义单链表的结点类型,实现对单链表的一些基本操作和具体 的函数定义,了解并掌握单链表的类定义以及成员函数的定义与调用。 2.掌握单链表基本操作及两个有序表归并、单链表逆置等操作的实现。二实验要求 1.预习C语言中结构体的定义与基本操作方法。 2.对单链表的每个基本操作用单独的函数实现。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三实验内容 1.编写程序完成单链表的下列基本操作: (1)初始化单链表La。 (2)在La中第i个元素之前插入一个新结点。 (3)删除La中的第i个元素结点。 (4)在La中查找某结点并返回其位置。 (5)打印输出La中的结点元素值。 2 .构造两个带有表头结点的有序单链表La、Lb,编写程序实现将La、 Lb合并成一个有序单链表Lc。 合并思想是:程序需要3个指针:pa、pb、pc,其中pa,pb分别指向La表与Lb表中当前待比较插入的结点,pc 指向Lc表中当前最后一个结点。依次扫描La和Lb中的元素,比较当前元素的值,将较小者链接到*pc 之后,如此重复直到La或Lb结束为止,再将另一个链表余下的内容链接到pc所指的结点之后。 3.构造一个单链表L,其头结点指针为head,编写程序实现将L逆置。 (即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。) 四思考与提高 1.如果上面实验内容2中合并的表内不允许有重复的数据该如何操作? 2.如何将一个带头结点的单链表La分解成两个同样结构的单链表Lb,Lc,使得Lb中只含La表中奇数结点,Lc中含有La表的偶数结点?

银行家死锁避免算法模拟

银行家死锁避免算法模拟 一.课程设计目的 通过本次实验掌握银行家死锁避免算法的基本思想。当进程提出资源申请时,能够用该算法判断是否拒绝进程请求。 二.课程设计摘要 银行家算法: 我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。 四.课程设计原理分析 在多道程序系统中,虽可借助于多个进程的并发执行,来改善系统的资源利用率,提高系统的吞吐量,但可能发生一种危险——死锁。所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵局状态时,若无外力作用,它们都将无法再向前推进。为保证系统中诸进程的正常运行,应事先采取必要的措施,来预防死锁。最有代表性的避免死锁的方法,是Dijkstra的银行家算法。 死锁: 死锁的产生,必须同时满足四个条件,第一个为互斥条件,即一个资源每次只能由一个进程占用;第二个为请求和保持条件,指进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进

程阻塞,但又对自己已获得的其他资源保持不放;第三个为非剥夺条件,即在出现死锁的系统中一定有不可剥夺使用的资源;第四个为循环等待条件,系统中存在若干个循环等待的进程,即其中每一个进程分别等待它前一个进程所持有的资源。防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。 银行家算法原理: 银行家算法是避免死锁的一种重要方法,通过编写一个简单的银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。通过这个算法可以用来解决生活中的实际问题,如银行贷款等。 银行家算法,顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行家资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。如果资源分配不得到就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,,每个进程的资源需求总量不能超过系统拥有的资源总数, 银行算法进行资源分配可以避免死锁. 算法思想: 将一定数量的资金供多个用户周转使用,当用户对资金的最大申请量不超过现存资金时可接纳一个新客户,客户可以分期借款,但借款总数不能超过最大的申请量。银行家对客户的借款可以推迟支付,但是能够使客户在有限的时间内得到借款,客户得到所有的借款后能在有限的时间内归还。 用银行家算法分配资源时,测试进程对资源的最大需求量,若现存资源能满足最大需求就满足当前进程的申请,否则推迟分配,这样能够保证至少有一个进程可以得到所需的全部资源而执行到结束,然后归还资源,若OS能保证所有进程在有限的时间内得到所需资源则称系统处于安全状态。

操作系统实验报告利用银行家算法避免死锁完整版

操作系统实验报告利用 银行家算法避免死锁 Document serial number【NL89WT-NY98YT-NC8CB-NNUUT-NUT108】

计算机操作系统实验报告题目利用银行家算法避免死锁 一、实验目的: 1、加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。 2、要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用银行家算法,有效的防止和避免死锁的发生。 二、实验内容: 用银行家算法实现资源分配: 设计五个进程{p0,p1,p2,p3,p4}共享三类资源{A,B,C}的系统,例如,{A,B,C}的资源数量分别为10,5,7。进程可动态地申请资源和释放资源,系统按进程的申请动态地分配资源,要求程序具有显示和打印各进程的某一个时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。 三、问题分析与设计: 1、算法思路: 先对用户提出的请求进行合法性检查,即检查请求是否大于需要的,是否大于可利用的。若请求合法,则进行预分配,对分配后

的状态调用安全性算法进行检查。若安全,则分配;若不安全,则拒绝申请,恢复到原来的状态,拒绝申请。 2、银行家算法步骤: (1)如果Requesti<or =Need,则转向步骤(2);否则,认为出错,因为它所需要的资源数已超过它所宣布的最大值。 (2)如果Request<or=Available,则转向步骤(3);否则,表示系统中尚无足够的资源,进程必须等待。 (3)系统试探把要求的资源分配给进程Pi,并修改下面数据结构中的数值: Available=Available-Request[i]; Allocation=Allocation+Request; Need=Need-Request; (4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。 3、安全性算法步骤: (1)设置两个向量 ①工作向量Work。它表示系统可提供进程继续运行所需要的各类资源数目,执行安全算法开始时,Work=Allocation; ②布尔向量Finish。它表示系统是否有足够的资源分配给进程,使之运行完成,开始时先做Finish[i]=false,当有足够资源分配给进程时,令Finish[i]=true。 (2)从进程集合中找到一个能满足下述条件的进程:

操作系统第五章复习资料

第五章设备管理 1、试说明设备控制器的组成。P163 答:设备控制器的组成由设置控制器与处理机的接口;设备控制器与设备的接口;I/O 逻辑。 2、为了实现CPU与设备控制器间的通信,设备控制器应具备哪些功能?P162-P163 答:基本功能:接收和识别命令;数据交换;标识和报告设备的状态;地址识别;数据缓冲;差错控制。 3、什么是字节多路通道?什么是数组选择通道和数组多路通道?P164-P165 答:1、字节多路通道:这是一种按字节交叉方式工作的通道。它通常都含有许多非分配型子通道,其数量可从几十到数百个,每个子通道连接一台I/O 设备,并控制该设备的I/O 操作。这些子通道按时间片轮转方式共享主通道。只要字节多路通道扫描每个子通道的速率足够快,而连接到子通道上的设备的速率不是太高时,便不致丢失信息。2、数组选择通道:字节多路通道不适于连接高速设备,这推动了按数组方式进行数据传送的数组选择通道的形成。3、数组多路通道:数组选择通道虽有很高的传输速率,但它却每次只允许一个设备数据。数组多路通道是将数组选择通道传输速率高和字节多路通道能使各子通道(设备)分时并行操作的优点相结合而形成的一种新通道。它含有多个非分配型子通道,因而这种通道既具有很多高的数据传输速率,又能获得令人满意的通道利用率。 4、如何解决因通道不足而产生的瓶颈问题?P166 答:解决“瓶颈”问题的最有效的方法,便是增加设备到主机间的通路而不增加通道,就是把一个设备连接到多个控制器上,而一个控制器又连接到多个通道上。多通路方式不仅解决了“瓶颈”问题。而且提高了系统的可靠性,因为个别通道或控制器的故障不会使设备和存储器之间没有通路。 5、试对VESA及PCI两种总线进行比较。P167 答:1、VESA 该总线的设计思想是以低价位迅速点领市场。VESA 总线的带宽为32 位,最高传输速率为132Mb/s。VESA 总线仍存在较严重的缺点,它所能连接的设备数仅为2—4 台,在控制器中无缓冲,故难于适应处理器速度的不断提高,也不能支持后来出现的Pentium 微机。2、PC 随着Pentium 系列芯片的推出,PCI 在CPU 和外设间插入一复杂的管理层,用于协调数据传输和提供一致的接口。在管理层中配有数据缓冲,通过该缓冲可将线路的驱动能力放大,使PCI 最多能支持10 种外设,并使高时钟频率的CPU 能很好地运行,最大传输速率可达132Mb/s。PCI 即可连接ISA、EISA 等传统型总线,又可支持Pentium 的64 位系统,是基于奔腾等新一代微处理器而发展的总线。 6、试说明推动I/O控制发展的主要因素是什么?P167 答:在I/O 控制方式的整个发展过程中,始终贯穿着这样一条宗旨,即尽量减少主机对I/O 控制的干预,把主机从繁杂的I/O 控制事务中解脱出来,以便更多地去完成数据处理任务。 7、有哪几种I/O控制方式?各适用于何种场合?P167-P170 答:1、程序I/O 方式:2、中断驱动I/O 控制方式:3、直接存储器访问(DMA)4、I/O 通道控制方式: 8、试说明DMA的工程流程。P170图要画 答:当CPU 要从磁盘读入一数据块时,便向磁盘控制器发送一条读命令。该命令被送到其中的命令寄存器(CR)中。同时,还须发送本次要将数据读入的内存起

操作系统之调度算法和死锁中的银行家算法习题答案

1.有三个批处理作业,第一个作业10:00 到达,需要执行2 小时;第二个作业在10:10 到达,需要执行1 小时;第三个作业在10:25 到达,需要执行25 分钟。分别采用先来先服务,短作业优先和最高响应比优先三种调度算法,各自的平均周转时间是多少? 解: 先来先服务: (结束时间=上一个作业的结束时间+执行时间 周转时间=结束时间-到达时间=等待时间+执行时间) 短作业优先: 1)初始只有作业1,所以先执行作业1,结束时间是12:00,此时有作业2和3; 2)作业3需要时间短,所以先执行; 最高响应比优先: 高响应比优先调度算法既考虑作业的执行时间也考虑作业的等待时间,综合了先来先服务和最短作业优先两种算法的特点。 1)10:00只有作业1到达,所以先执行作业1; 2)12:00时有作业2和3, 作业2:等待时间=12:00-10:10=110m;响应比=1+110/60=2.8; 作业3:等待时间=12:00-10:25=95m,响应比=1+95/25=4.8; 所以先执行作业3 2.在一单道批处理系统中,一组作业的提交时刻和运行时间如下表所示。试计算一下三种作业调度算法的平均周转时间T 和平均带权周转时间W。 (1)先来先服务;(2)短作业优先(3)高响应比优先

解: 先来先服务: 短作业优先: 作业顺序: 1)8:00只有作业1,所以执行作业1; 2)9:00有作业2和3,作业3短,所以先执行3; 3)9:12有作业2和4,作业4短,所以先执行4; 高响应比优先: 作业顺序: 1)8:00只有作业1,所以执行作业1; 2)9:00有作业2和3 作业2等待时间=9:00-8:30=30m,响应比=1+30/30=2; 作业3等待时间=9:00-9:00=0m,响应比=1+0/12=1; 所以执行作业2; 3)9:30有作业3和4 作业3等待时间=9:30-9:00=30m,响应比=1+30/12=3.5; 作业4等待时间=9:30-9:06=24m,响应比=1+24/6=5;

操作系统第五章复习资料

第五章习题 一、选择题 1、在一般大型计算机系统中,主机对外设的控制可通过通道、控制器和设备三个层次来实现。从下述叙述中选出一条正确的叙述。()(1)控制器可控制通道,设备在通道控制下工作; (2)通道控制控制器,设备在控制器控制下工作; (3)通道和控制器分别控制设备; (4)控制器控制通道和设备的工作。 2、从下面关于设备属性的叙述中,选择一条正确的论述。()(1)字符设备的一个基本特征是可寻址的,即能指定输入时的原地址和输出时的目标地址;(2)共享设备是指在同一时刻允许多个进程同时访问的设备; (3)共享设备必须是可寻址的和随机访问的设备; (4)在分配共享设备和独占设备时,都可能引起进程死锁; 3、通道是一种特殊的(A),具有(B)能力。主机的CPU与通道可以并行工作,并通过(C)实现彼此之间的通信和同步。 A:(1)I/O设备;(2)设备控制器;(3)处理机;(4)I/O控制器 B:(1)执行I/O指令集;(2)执行CPU指令集;(3)传输I/O命令;(4)运行I/O进程C:(1)I/O指令;(2)I/O中断;(3)I/O指令和I/O 中断;(4)操作员 4、在I/O 设备控制的发展过程中,最主要的推动因素是(A)。提高I/O速度和设备利用率,在OS中主要依靠(B)功能。使用户所编制的程序与实际使用的物理设备无关是由(C)功能实现的。 A:(1)提高资源利用率;(2)提高系统吞吐量;(3)减少主机对I/O控制的干预; (4)提高CPU与I/O设备的并行操作吃呢高度 B,C:(1)设备分配;(2)缓冲管理;(3)设备管理;(4)设备独立性;(5)虚拟设备5、磁盘属于(A),其信息的存取是以(B)为单位的;磁盘的I/O控制主要采取(C)方式;打印机的I/O控制主要采取(D)方式。 A:(1)字符设备;(2)独占设备;(3)块设备;(4)虚拟设备 B:(1)位(bit)(2)字节(3)帧(4)固定长数据块 C、D:(1)程序I/O方式;(2)程序终端;(3)DMA;(4)Spooling 6、在程序I/O方式中,对于输出设备,准备就绪是指(A)。 A:(1)输出缓冲区已空;(2)输出缓冲区已有数据;(3)输出设备已开始工作; (4)输出设备已收到I/O指令 7、在利用RS-232接口进行通信时,其通道速率为9.6kb/s (b为bit)。如果在通信接口中仅设置了一个8位寄存器作为缓冲寄存器,这意味着大约每隔(A)的时间便要中断一次CPU,且要求CPU必须在(B)时间内予以响应。 A,B:(1)80μs (2)0.1ms ;(3)0.8ms ;(4)1ms ;(5)8ms 8、假定把磁盘上一个数据块中的信息输入到一单缓冲区中的时间T为100μs,将缓冲区中的数据传送到用户区的时间M为50μs,而CPU对这一块数据进行计算的时间C为50μs。这样,系统对每一块数据的处理时间为(A);如果将单缓冲区改为双缓冲区,则系统对每一块数据的处理时间为(B)。 A,B:(1)50μs;(2)100μs;(3)150μs ;(4)200μs; (5)250μs 9、操作系统中采用缓冲技术的目的是为了增强系统(A)的能力;为了使多个进程能有效地同时处理输入和输出,最好使用(B)。 A:(1)串行操作;(2)并行操作;(3)控制操作;(4)中断操作

实验四 死锁避免的算法

实验六死锁避免的算法 【实验目的】 1、了解死锁避免的原理。 2、研究银行家算法的实现方法。 【实验内容】 编程实现银行家算法。 通过编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁地发生。要求如下: (1)模拟一个银行家算法; (2)初始化时让系统拥有一定的资源; (3)用键盘输入的方式申请资源; (4)如果预分配后,系统处于安全状态,则修改系统的资源分配情况; (5)如果预分配后,系统处于不安全状态,则提示不能满足请求, 【实验报告】 1、列出调试通过程序的清单,并附上文档说明。 2、总结上机调试过程中所遇到的问题和解决方法及感想。 【实验相关资料】 一、死锁概念 多个并发进程,每个进程占有部分资源,又都等待其它进程释放所占资源,造成均不能向前推进的现象。 二、死锁的避免 死锁避免原理就是使系统始终处于安全状态。 安全状态:所谓安全状态是指能够找到一个安全序列,系统能够按照这个安全序列依次为进程分配资源,使所有进程都能执行完毕,如果找不到这样的安全序列,系统就处于不安全状态。 三、银行家算法 银行家算法要求每个进程的最大资源需求,其基本思想是:始终保持系统处于安全状态,当进程提出资源请求时,系统先进行预分配,再判断系统分配后是否仍然处于安全状态。如果仍然处于安全状态,就进行实际分配;如果处于不安全状态,则拒绝该进程的资源请求。

四、银行家算法相关数据结构 1. 最大需求矩阵: d (t)=?????? ? ??? ???nm n n m m d d d d d d d d d .........212222111211 其中,行表示进程,列表示资源,如:d ij =5表示第 i 个进程最多需要j 类资源5个。 2. 资源分配矩阵: a(t)=?????? ? ??? ???nm n n m m a a a a a a a a a .........212222111211 元素a ij =8表示分配给第 i 进程8个j 类资源。 3. 需求矩阵: b(t)=?????? ? ??? ???nm n n m m b b b b b b b b b .........212222111211 元素b ij =3表示第i 类进程还需要3个j 类资源。 最大需求矩阵=分配矩阵+需求矩阵,即d(t)=a(t)+b(t)。

避免死锁的方法有哪些

1.避免死锁的方法有哪些?答案:有一种最简单的就是:全部程序禁用,然后重启自己需要 的程序。用行级锁,不去征用大表的主键,用小事务。 2.在Sybase数据库中注册用户与数据库用户有什么区别? 答案:Sybase中没有注册用户数这个说法,如果是LICENSE中的,技术上可以忽略,用户 数EE版可以设很大,几万,SMB版可以设256个。 3.在MS SQL_Server 数据库中通过什么约束保证数据库的实体完整性 答案:可以通过建立唯一的索引、PRIMARY KEY约束、UNIQUE约束或IDENTITY约束来实现 实体完整性 4.内存有哪几种存储组织结构.请分别加以说明 中的Wait() 和notify()方法使用时应注意些什么? 答案:Wait()和notify():如果条件不满足,则等待。当条件满足时,等待该条件的线程将 被唤醒。一般用在synchronized机制中例如:线程Asynchronized(obj) {while(!condition) {();}();} 当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于 是线程A就wait()。在另一线程B中,如果B更改了某些条件,使得线程A的condition 条件满足了,就可以唤醒线程A:线程Bsynchronized(obj) {condition = true;();}需要 注意的概念是:◆调用obj的wait(), notify()方法前,必须获得obj锁,也就是 必须写在synchronized(obj){……} 代码段内。◆调用()后,线程A就释放了obj 的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj){……} 代码段内唤 醒A. ◆当()方法返回后,线程A需要再次获得obj锁,才能继续执行。◆如果A1, A2,A3都在(),则B调用()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。 ◆()则能全部唤醒A1,A2,A3,但是要继续执行()的下一条语句,必须获得obj锁, 因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj 锁之后才能继续执行。◆当B调用notifyAll的时候,B正持有obj锁,因此,A1,A2, A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1, A2,A3中的一个才有机会获得锁继续执行。 6.用户输入一个整数.系统判断,并输出是负数还是非负数,请设计测试用例. 7.操作系统中的同步和互诉解决了什么问题 答案:同步:各个进程不知对方名字,但通过某些对象(如I/O缓冲区)的共同存取来协同 完成一项任务。互斥:互斥跟临界资源有关,因为计算机的某些资源有限,所以必须通过互 斥操作防止进程之间竞争临界资源而发生死锁,互斥操作用PV原语实现。 8.UNIX 中init 1.不许用中间变量,把String ABCDE 倒转 public class StringDemo { public static void main(String[]args) { String str="ABCD"; for (int i = ()-1; i >=0; i--) { str+=(i)); } str=("ABCD".length(), ()); }} 个数求第2大的数,不许用排序算法 3.排序算法的测试用例 1, 合并有序链表 2, 删除字符串中相邻重复元素 3, 给出了二叉树结构,要求写出广度优先遍历 4, 给定整型数组,写代码找出数组中第二大元素 5, 有关菲波那契数列问题 1.怎么判断鼠标有没有选中一条线段(如很靠近,鼠标点和线段之间的距离小于5毫米) 2.求一个矩形的中心点和一个点的连线与矩形边的交点坐标(矩形左上角坐标给出,长、宽

第5章 死锁 练习题参考答案

第五章死锁练习题参考答案 (一)单项选择题 1.D 2.C 3.B 4.D 5.A 6.C 7.D (二)填空题 1.死锁2.资源管理不得当,并发执行时3.占有并等待资源,循环等待资源4.等价的5.没有死锁6.一个条件不成立7.静态分配资源,释放已占资源8.预分配资源.开始执行前9.没有占用资源10.抢夺11.主存空间,处理器12.按序分配13安全状态14.避免死锁15.银行家算法16.死锁的避免17.n(x- 1)+l<=m 18.死锁检测方法19判断系统,解除死锁20.占用表,等待表21.尚需量,剩余量22终止,抢夺资源23.校验点24.防止,检测 (三)简答题 1.若系统中存在一组进程、它们中的每—个进程都占用了某种资源而又都在等待其中另一个进程所占的资源,这种等待永远不能结束,则说明系统出现了死锁。产生死锁的原因有两个:一是操作系统对资源的管理不当,二是没有顾及进程并发执行时可能出现的情况。 2.采用某些资源分配策略使死锁的四个必要条件之一不成立,就能防止死锁。除第一个条件互斥使用资源没有对应策略外,对占有并等待资源、不可抢夺资源和循环等待资源这三个条件可采用静态分配资源,释放已占资源,抢夺式分配资源和按序分配资源等资源分配策略。 3.如果操作系统能保证所有的进程在有限的时间内得到需要的全部资源,则称系统处于安全状态。常用银行家算法动态地检测系统中的资源分配情况和进程对资源的需求情况进行资源分配,确保系统处于安全状态。 4解决死锁问题有以下三种方法:(1)死锁的防止。系统按预定的策略为进程分配资源,这些分配策略能使死锁的四个必要条件之一不成立,从而使系统不产生死锁。(2)死锁的避免。系统动态地测试资源分配情况,仅当能确保系统安全时才给进程分配资源。(3)死锁的检测。对资源的申请和分配不加限制,只要有剩余的资源就可把资源分配给申请者,操作系统要定时判断系统是否出现了死锁,当有死锁发生时设法解除死锁。5.用抢夺资源的方式解除死锁时要注意三点:(1)抢夺进程资源时希望付出的代价最小。(2)为被抢夺者的恢复准备好条件,如返回某个安全状态,并记录有关信息。(3)防止被抢夺资源的进程“饿死”,一般总是从执行时间短的进程中抢夺资源。 (四)应用题 1.(1)根据表,P1,P2和P3三个进程尚需资源数分别是4,5和1,系统的资源剩余量为2,若把剩余的资源量全部分配给P2,系统产已无资源可分配,使三个进程都等待资源而无法完成,形成死锁。所以不能先满足进程P2的要求。 (2)可先为进程P3分配1个资源,当它归还3个资源后,这样共有4个可分配资源,可满足P1申请1个资源的要求,再分配3个资源给进程P1,待P1归还7个资源后,先满足P2申请2个资源的请求,分配给进程P2,再分配3个资源给P2,使它完成。 2.(1)系统目前尚余有的资源数为(2,6,2,1),五个进程尚需的资源数分别是A:(2,0,0,0) ; B:(0,0,0,0); C:(4,6,2,0) ; D:(5,7,0,0); E:(0,0,2,1);由于进程B己满足了全部资源需求,它在有限时间内会归还这些资源,因此可分配资源达到(3,6,4,1),这样就可分配给进程A;等A归还资源后,可分配资源达到(6,12,6,1),再分配给进程C;之后可分配资源会达到(7,12,10,1),分配给进程D并等待一段时间后,可分配资源将达到(7,12,10,2),最后,可分配给进程E,满足其全部请求。所以说目前系统处于安全状态。 (2)若此时给进程D分配(2,5,0,0)个资源,进程D尚需(3,2,0,0),则系统剩余的资源量为(0,

相关文档
最新文档