Operating Systems


Deadlock




Ahmad Yoosofan

Spring 2023

University of Kashan

yoosofan@mail.com



Deadlock in real situations





Resource-Allocation Graph

  • The set of Processes: P = {P0, P1, P2}
  • The set of Resources: R = {R0, R1, R2, R3}
  • The set of Edges: E = {
    • R0 → P0,


Resource-Allocation Graph

  • The set of Processes: P = {P0, P1, P2}
  • The set of Resources: R = {R0, R1, R2, R3}
  • The set of Edges: E = {
    • R0 → P0,
    • R1 → P0,
    }


Request

  • The set of Processes: P = {P0, P1, P2}
  • The set of Resources: R = {R0, R1, R2, R3}
  • The set of Edges: E = {
    • R0 → P0,
    • R1 → P0,
    • P1 → R1,
    }


Resource-Allocation Graph

  • The set of Processes: P = {P0, P1, P2}
  • The set of Resources: R = {R0, R1, R2, R3}
  • The set of Edges: E = {
    • R0 → P0,
    • R1 → P0,
    • P1 → R1,
    • R2 → P1,
    • R3 → P2
    }



Deadlock Example





Wait-For Graph

Resource-Allocation GraphWait-For Graph


Multiple Instances

  • The set of Processes; P = {P0, P1, P2}
  • The set of Resources; R = {R0, R1, R2, R3}
  • The set of Edges ; E = {
    • R0 → P0,
    • R1 → P0,
    • P1 → R1,
    • R2 → P1,
    • R3 → P2
    • }
  • One instances of resource type R0
  • Two instances of resource type R1
  • One instances of resource type R2
  • Three instances of resource type R3

Deadlock



Non deadlockDeadlock

Deadlock



Non deadlockDeadlock



Necessary Conditions of deadlock



  1. Mutual exclusion
  2. Hold and wait
  3. No preemption
  4. Circular wait
    • R0 < R1 < R2 < ... < Rm




Deadlock Detection



  1. Single Instance of Each Resource Type
    • Finding loop in a graph
  2. Several Instances of a Resource Type
    • Available. A vector of length m indicates the number of available resources of each type.
      • Avail = [ R0, R1, ... , Rm ]
    • Allocation. An (n * m) matrix defines the number of resources of each type currently allocated to each process.
    • Request. An (n * m) matrix indicates the current request of each process. If Requesti,j equals k, then process Pi is requesting k more instances of resource type Rj.

Example of Resource-Allocation

Resources =
R0 R1 R2 R3
2 1 2 2
Avaiable =
R0 R1 R2 R3
0 0 0 1
Allocation =
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 1 0
P3 0 0 1 1
Request =
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 0 0 0

Example of Resource-Allocation

Resources =
R0 R1 R2 R3
2 1 2 2
Avaiable =
R0 R1 R2 R3
0 0 0 1
Allocation =
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 1 0
P3 0 0 1 1
Request =
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 0 0 0
  1. Process 3
    • finish[3] == false and Request[3] ≤ work
    • finish[3] = true; work += Allocatin[3];
    • work = { 0, 0, 1, 2 }

Example of Resource-Allocation

Resources =
R0 R1 R2 R3
2 1 2 3
Avaiable =
R0 R1 R2 R3
0 0 0 1
Allocation =
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 1 0
P3 0 0 1 1
Request =
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 0 0 0
  1. Process 3
    • finish[3] == false and Request[3] ≤ work
    • finish[3] = true; work += Allocation[3];
    • work = { 0, 0, 1, 2 }
  2. Process 1
    • finish[1] == false and Request[1] ≤ work
    • finish[1] = true; work += Allocation[1];
    • work = { 1, 1, 1, 2 }

Example of Resource-Allocation

Resources =
R0 R1 R2 R3
2 1 2 3
Avaiable =
R0 R1 R2 R3
0 0 0 1
Allocation =
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 1 0
P3 0 0 1 1
Request =
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 0 0 0
  1. Process 3
    • finish[3] == false and Request[3] ≤ work
    • finish[3] = true; work += Allocation[3];
    • work = { 0, 0, 1, 2 }
  2. Process 1
    • finish[1] == false and Request[1] ≤ work
    • finish[1] = true; work += Allocation[1];
    • work = { 1, 1, 1, 2 }
  3. Process 2
    • finish[2] == false and Request[2] ≤ work
    • finish[2] = true; work += Allocation[2];
    • work = { 1, 1, 2, 2 }

Example of Resource-Allocation

Resources =
R0 R1 R2 R3
2 1 2 2
Avaiable =
R0 R1 R2 R3
0 0 0 1
Allocation =
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 1 0
P3 0 0 1 1
Request =
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 0 0 0
  1. Process 3
    • finish[3] == false and Request[3] ≤ work
    • finish[3] = true; work += Allocation[3];
    • work = { 0, 0, 1, 2 }
  2. Process 1
    • finish[1] == false and Request[1] ≤ work
    • finish[1] = true; work += Allocation[1];
    • work = { 1, 1, 1, 2 }
  3. Process 2
    • finish[2] == false and Request[2] ≤ work
    • finish[2] = true; work += Allocation[2];
    • work = { 1, 1, 2, 2 }
  4. Process 0
    • finish[0] == false and Request[0] ≤ work
    • finish[0] = true; work += Allocation[0];
    • work = { 2, 1, 2, 2 }
  5. Sequence of execution: 3, 1, 2, 0
  6. Sequence of execution: 3, 1, 0, 2

Deadlock Example 1

Resources=
R0 R1 R2 R3
2 1 2 2
Avaiable=
R0 R1 R2 R3
0 0 0 1
Allocation=
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 1 0
P3 0 0 1 1
Request=
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 1 0 0
There is no process which its Request[i] ≤ work

Deadlock Example 2

Resources=
R0 R1 R2 R3
2 1 2 2
Avaiable=
R0 R1 R2 R3
0 0 0 2
Allocation=
R0 R1 R2 R3
P0 1 0 0 0
P1 1 1 0 0
P2 0 0 2 0
P3 0 0 0 0
Request=
R0 R1 R2 R3
P0 0 1 0 0
P1 0 0 1 0
P2 1 0 0 0
P3 0 0 0 1

Deadlock



  1. Initialize Work = Available.
         for i in range(0, n): 
           if Allocation[i] <> 0:  Finish[i] = false. 
           else: Finish[i] = true.
      
  2. Find an index i such that: (a) Finish[i] == false (b) Request[i] ≤ Work
    If no such i exists, go to step 4.
  3. Work += Allocation[i] and Finish[i] = true
    Go to step 2.
  4. If Finish[i] == false for some i, 0 ≤ i < n, then the system is in a deadlock

Deadlock detection (Psudo C++ code)

/* ********************* 1   ************************** */
bool finish[N]; int work[M];  int i,j; bool flag=true;
work = Available
for(i=0; i<N; i++)
  if(Allocation[i]!=0)    finish[i]=false;
  else                    finish[i]=true;
/* ********************* 2   ************************** */
flag=true;
while(flag==true){
  flag=false;
  for(i=0;i<N;i++)
    if( (finish[i] == false) && (Request[i] <= work){
          finish[i]=true;
          work += Allocation[i];
          flag=true;
        }
    }
}/* ********************* 3   ************************** */
flag = false;
for(i=0;i<N; i++)
  if(finish[i] == false){ flag=true;    cout<<"process "<<i<<" is deadlocked."<<endl;  }
if(flag==true)  cout<<"The system is deadlocked"<<endl;
else cout<<"The system is not deadlocked"<<endl;

Deadlock detection (Python code)

N = 100 # number of Processes
M = 200 # number of Resources
Available = [0] * M # array(M)
Allocation = [[0] * M] * N # array(N,M)
Request = [[0] * M] * N # array(N,M)
################################################
finish  = [False] * N #array(N)
work = Available.copy()
flag = True
for i in range(0, N):
  if all(k == 0 for k in Allocation[i]):
    finish[i] = True
################################################
while flag == True:
  flag = False
  for i in range(0, N):
    if finish[i] == False and all(k<=m for k, m in zip(Request[i], work)):
      finish[i] = True
      work = [x+y for x, y in zip(work, Allocation[i])]
      flag = True
################################################
deadlocked = [i for i in range(0, N) if finish[i] == False]
if len(deadlocked) !=0:
  print("The system is deadlocked")
else:
  print("The system is not deadlocked")

Recovery from Deadlock


  1. Process Termination
    1. Abort all deadlocked processes.
    2. Abort one process at a time until the deadlock cycle is eliminated.
      1. What the priority of the process is
      2. How long the process has computed and how much longer the process will compute before completing its designated task
      3. How many and what types of resources the process has used (for example, whether the resources are simple to preempt)
      4. How many more resources the process needs in order to complete
      5. How many processes will need to be terminated
      6. Whether the process is interactive or batch
  2. Resource Preemption
    1. Selecting a victim.
    2. Rollback.
    3. Starvation.

Other Considerations about Dead Lock Detection

Deadlock Avoidance(Banker's Algorithm) 1

MAX =
R0 R1 R2
P0 1 1 0
P1 0 1 1
P2 1 0 1
Claim edge

Deadlock Avoidance(Banker's Algorithm) 2

MAX =
R0 R1 R2
P0 1 1 0
P1 0 1 1
P2 1 0 1
Need = MAX - Allocation Need =
R0 R1 R2
P0 0 1 0
P1 0 0 1
P2 1 0 0
Avaiable=[ 0 , 0 , 0 ]
Need =
R0 R1 R2
P0 0 1 0
P1 0 0 1
P2 1 0 1
Avaiable=[ 0 , 0 , 1 ]
Safe Sequence P1 , P0 , P2

Safety Algorithm



  1. Variables
    1. int work[m] = Avaiable
    2. bool Finish[n]={false}
    3. int Need[n][m] = MAX - Allocation
  2. while exists i such that ( (Finish[i] == false) and ( Need[i] ≤ Work) )
    1. Work = Work + Allocation[i]
    2. Finish[i] = true
  3. If Finish[i] ==true for all i, then the system is in a safe state.


Resource-Request Algorithm




  1. If Requesti ≤ Needi;, go to step 2. Otherwise, raise an error condition, since the process has exceeded its maximum claim.
  2. If Requesti ≤ Available, go to step 3. Otherwise, P; must wait, since the resources are not available.
  3. Have the system pretend to have allocated the requested resources to process P; by modifying the state as follows:
    • Available= Available- Requesti
    • Allocationi =Allocationi +Requesti
    • Needi =Needi - Requesti
  4. If the resulting resource-allocation state is safe, the transaction is completed, and process P; is allocated its resources. However, if the new state is unsafe, then P; must wait for Request;, and the old resource-allocation state is restored

END

Γ(t)=limnn!ntt(t+1)(t+n)=1tn=1(1+1n)t1+tn=eγttn=1(1+tn)1etn\Gamma(t) = \lim_{n \to \infty} \frac{n! \; n^t}{t \; (t+1)\cdots(t+n)}= \frac{1}{t} \prod_{n=1}^\infty \frac{\left(1+\frac{1}{n}\right)^t}{1+\frac{t}{n}} = \frac{e^{-\gamma t}}{t} \prod_{n=1}^\infty \left(1 + \frac{t}{n}\right)^{-1} e^{\frac{t}{n}}
R 0 R 1 R 2 R 3 P 0 1 0 1 1 2 3 1 0 1 P 1 P 2


الگوریتم تخصیص منابع



  1. اگر Need ≤ Request آن‌گاه خطایی را ایجاد کن زیرا فرایند بیشتر از مقدار حداکثری که گفته است منبع می‌خواهد دریافت کند وگرنه به گام ۲ برو
  2. اگر فرایندی با شمارهٔ i یافت شد که Requesti ≤ Available, باشد آن‌گاه به گام ۳ برو وگرنه فرایند i ام باید منتظر بماند زیرا منبع درخواستی‌اش در دسترس نیست.
  3. فرض می‌کنیم که منابع مورد نیاز فرایند را در اختیارش بگذاریم یعنی کارهای زیر را انجام دهیم
    • Available= Available- Requesti
    • Allocationi =Allocationi +Requesti
    • Needi =Needi - Requesti
  4. الگوریتم امن بودن را روی وضعیت شبیه‌سازی شدهٔ کنونی اجرا می‌کنیم
  5. اگر وضعیت امن بود تخصیص واقعی را انجام می‌دهیم وگرنه تخصیص را انجام نمی‌دهیم و وضعیت آرایه‌ها و ماتریس‌ها را به حالت پیش از تغییر در گام ۳ برمی‌گردانیم