线程死锁

来源:互联网 发布:四六级听力软件 编辑:程序博客网 时间:2024/05/29 16:43
  1. 调研什么是死锁
    死锁 (deallocks): 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或 系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程(线程)在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象 死锁。
    一种交叉持锁死锁的情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被其它线程占用并堵塞了的资源。例如,如果线程 1 锁住了记录 A 并等待记录 B,而线程 2 锁住了记录 B 并等待记录 A,这样两个线程就发生了死锁现象。在计算机系统中 , 如果系统的资源分配策略不当,更常见的可能是程序员写的程序有错误等,则会导致进程因竞争资源不当而产生死锁的现象。

  2. 调研死锁产生的4个必要条件是什么
    (1) 互斥条件:一个资源每次只能被一个进程(线程)使用。
    (2) 请求与保持条件:一个进程(线程)因请求资源而阻塞时,对已获得的资源保持不放。
    (3) 不剥夺条件 : 此进程(线程)已获得的资源,在末使用完之前,不能强行剥夺。
    (4) 循环等待条件 : 多个进程(线程)之间形成一种头尾相接的循环等待资源关系。

  3. 调研如何避免死锁,常见算法与原理。
    (1)终止(或撤销)进程。终止(或撤销)系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态中解除出来。
    (2)抢占资源。从一个或多个进程中抢占足够数量的资源,分配给死锁进程,以打破死锁状态。
    (3)不用死锁。

银行家算法:
首先需要定义状态和安全状态的概念。系统的状态是当前给进程分配的资源情况。因此,状态包含两个向量Resource(系统中每种资源的总量)和Available(未分配给进程的每种资源的总量)及两个矩阵Claim(表示进程对资源的需求)和Allocation(表示当前分配给进程的资源)。安全状态是指至少有一个资源分配序列不会导致死锁。当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确定其结果是否还处于安全状态。如果是,同意这个请求;如果不是,阻塞该进程知道同意该请求后系统状态仍然是安全的。
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。

实现代码:

#include<STRING.H>#include<stdio.h>#include<stdlib.h>#include<CONIO.H>/*用到了getch()*/#defineM5/*进程数*/#defineN3/*资源数*/#defineFALSE0#defineTRUE1/*M个进程对N类资源最大资源需求量*/intMAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};/*系统可用资源数*/intAVAILABLE[N]={10,5,7};/*M个进程已分配到的N类数量*/intALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};/*M个进程已经得到N类资源的资源量*/intNEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};/*M个进程还需要N类资源的资源量*/intRequest[N]={0,0,0};voidmain(){inti=0,j=0;charflag;voidshowdata();voidchangdata(int);voidrstordata(int);intchkerr();showdata();enter:{printf("请输入需申请资源的进程号(从0到");printf("%d",M-1);printf("):");scanf("%d",&i);}if(i<0||i>=M){printf("输入的进程号不存在,重新输入!\n");gotoenter;}err:{printf("请输入进程");printf("%d",i);printf("申请的资源数\n");printf("类别:ABC\n");printf("");for(j=0;j<N;j++){scanf("%d",&Request[j]);if(Request[j]>NEED[i][j]){printf("%d",i);printf("号进程");printf("申请的资源数>进程");printf("%d",i);printf("还需要");printf("%d",j);printf("类资源的资源量!申请不合理,出错!请重新选择!\n");gotoerr;}else{if(Request[j]>AVAILABLE[j]){printf("进程");printf("%d",i);printf("申请的资源数大于系统可用");printf("%d",j);printf("类资源的资源量!申请不合理,出错!请重新选择!\n");gotoerr;}}}}changdata(i);if(chkerr()){rstordata(i);showdata();}elseshowdata();printf("\n");printf("按'y'或'Y'键继续,否则退出\n");flag=getch();if(flag=='y'||flag=='Y'){gotoenter;}else{exit(0);}}/*显示数组*/voidshowdata(){inti,j;printf("系统可用资源向量:\n");printf("***Available***\n");printf("资源类别:ABC\n");printf("资源数目:");for(j=0;j<N;j++){printf("%d",AVAILABLE[j]);}printf("\n");printf("\n");printf("各进程还需要的资源量:\n");printf("******Need******\n");printf("资源类别:ABC\n");for(i=0;i<M;i++){printf("");printf("%d",i);printf("号进程:");for(j=0;j<N;j++){printf("%d",NEED[i][j]);}printf("\n");}printf("\n");printf("各进程已经得到的资源量:\n");printf("***Allocation***\n");printf("资源类别:ABC\n");for(i=0;i<M;i++){printf("");printf("%d",i);printf("号进程:");/*printf(":\n");*/for(j=0;j<N;j++){printf("%d",ALLOCATION[i][j]);}printf("\n");}printf("\n");}/*系统对进程请求响应,资源向量改变*/voidchangdata(intk){intj;for(j=0;j<N;j++){AVAILABLE[j]=AVAILABLE[j]-Request[j];ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j];NEED[k][j]=NEED[k][j]-Request[j];}}/*资源向量改变*/voidrstordata(intk){intj;for(j=0;j<N;j++){AVAILABLE[j]=AVAILABLE[j]+Request[j];ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];NEED[k][j]=NEED[k][j]+Request[j];}}/*安全性检查函数*/intchkerr()//在假定分配资源的情况下检查系统的安全性{intWORK[N],FINISH[M],temp[M];//temp[]用来记录进程安全执行的顺序inti,j,m,k=0,count;for(i=0;i<M;i++)FINISH[i]=FALSE;for(j=0;j<N;j++)WORK[j]=AVAILABLE[j];//把可利用资源数赋给WORK[]for(i=0;i<M;i++){count=0;for(j=0;j<N;j++)if(FINISH[i]==FALSE&&NEED[i][j]<=WORK[j])count++;if(count==N)//当进程各类资源都满足NEED<=WORK时{for(m=0;m<N;m++)WORK[m]=WORK[m]+ALLOCATION[i][m];FINISH[i]=TRUE;temp[k]=i;//记录下满足条件的进程k++;i=-1;}}for(i=0;i<M;i++)if(FINISH[i]==FALSE){printf("系统不安全!!!本次资源申请不成功!!!\n");return1;}printf("\n");printf("经安全性检查,系统安全,本次分配成功。\n");printf("\n");printf("本次安全序列:");for(i=0;i<M;i++)//打印安全系统的进程调用顺序{printf("进程");printf("%d",temp[i]);if(i<M-1)printf("->");}printf("\n");return0;}