A deadlock occurs when two or more processes compete for resources during execution.
Four Conditions for deadlock:
1. mutex condition: A resource can only be used by one process at a time.
2. Request and retention conditions: when a process is blocked by requesting resources, it will not release the obtained resources. (Partial resource allocation)
3. No deprivation condition: the resources obtained by the process cannot be forcibly deprived before they are used up.
4. Cyclic waiting condition: a type of cyclic waiting resource relationship is formed between several processes.
The four conditions above are the four necessary conditions for deadlock generation. As long as one of the four conditions is not met, the deadlock will not occur.
Based on the preceding conditions, three preventive measures are listed:
1. Use the static resource allocation policy to break the "partial allocation" condition.
2. Process deprivation is allowed to use the resources occupied by other processes, thereby undermining the "irrevocable" condition.
3. Use the orderly Resource Allocation Method to break the "loop" condition.
Note: The mutex condition cannot be destroyed.
Deadlock AvoidanceAlgorithmThe most famous algorithm is Dijkstra's Banker algorithm.
Banker algorithm:
The basic idea is to determine whether the system is safe before allocating resources. It is the most representative algorithm to avoid deadlocks.
When the process cusneed puts forward a request [I], the banker's algorithm determines based on the following rules.
(1) If the request [cusneed] [I] <= need [cusneed] [I], convert it to (2); otherwise, an error occurs.
(2) If the request [cusneed] [I] <= available [cusneed] [I], convert it to (3). Otherwise, an error occurs.
(3) The system tries to allocate resources and modify relevant data:
Available [I]-= request [cusneed] [I];
Allocation [cusneed] [I] + = request [cusneed] [I];
Need [cusneed] [I]-= request [cusneed] [I];
(4) The system performs a security check. If the security check is performed, the allocation is established. Otherwise, the trial allocation is voided, the system is restored to its original state, and the process is waiting.
Security check algorithm:
(1) set two working vectors work = available; finish (all false)
(2) Find a process that meets the following conditions from the process set,
Finish = false;
Need <= work;
If found, execute (3); otherwise, execute (4)
(3) set the process to obtain resources and run smoothly until the process is completed to release the resources.
Work + = allocation;
Finish = true;
Goto (2)
(4) If all processes finish = true, it indicates security; otherwise, the system is not safe.
Banker algorithmCodeInstance:
# Include <stdio. h> # include <stdlib. h> # include <string. h> # define N 5 // number of processes # define m 3 // Resource Type int main () {int I, j; int A; int request [m]; // request resource Range int allocation [N] [m]; // The allocated resource matrix int need [N] [m]; // The requirement matrix int available [m]; // available resources // enter the allocated resources printf ("Enter allocated resources: \ n"); for (I = 0; I <N; I ++) {printf ("Enter the resources allocated by the % d process:", I + 1); For (j = 0; j <m; j ++) scanf ("% d", & allocation [I] [J]);} // enter the resources required by each process ("\ n, enter the resources required by each process: \ n"); for (I = 0; I <n; I ++) {printf ("Enter the resources required by the % d process:", I + 1); For (j = 0; j <m; j ++) scanf ("% d", & need [I] [J]);} // enter the available resource data printf ("\ n enter the available resource data:"); for (I = 0; I <m; I ++) scanf ("% d", & available [I]); While (1) {start: printf ("\ n please input several processes to send resource requests: "); scanf (" % d ", & A); // enter the printf (" \ n % d process resource requests :", a); for (I = 0; I <m; I ++) scanf ("% d", & request [I]); // Banker algorithm Step 1 for (I = 0; I <m; I ++) {If (! (Request [I] <= need [A-1] [I]) {printf ("P % d illegal request! ", A); printf (" cannot be assigned to the P % d process! ", A); goto start ;}// Banker algorithm Step 2 for (I = 0; I <m; I ++) {If (! (Request [I] <= available [I]) {printf ("P % d process blocking! ", A); printf (" cannot be assigned to the P % d process! ", A); goto start ;}// step 3 of the Banker algorithm: test allocation for (I = 0; I <m; I ++) {available [I] = available [I]-request [I]; alposition [A-1] [I] = allocation [A-1] [I] + request [I]; need [A-1] [I] = need [A-1] [I]-request [I];} // Banker algorithm Step 4: security check int finish [N] = {0, 0, 0}; int work [m]; for (I = 0; I <m; I ++) work [I] = available [I]; int flag = 1; while (flag = 1) {for (I = 0; I <n; I ++) {for (j = 0; j <m; j ++) {If (finish [I] = 0 & need [I] [J] <= work [J]) {If (j = M-1) {finish [I] = 1; printf ("\ NP % D process security check passed ", I + 1); For (j = 0; j <m; j ++) work [J] = work [J] + allocation [I] [J] ;}} continue ;}} int sum = 0; for (I = 0; I <N; I ++) sum = sum + finish [I]; If (sum = 5) Flag = 0 ;}for (I = 0; I <n; I ++) {If (finish [I] = 0) {printf ("trial allocation failed! Security check failed! "); Printf (" \ n cannot be assigned to the P % d process! ", A); available [I] = available [I] + request [I]; allocation [A-1] [I] = allocation [A-1] [I]-request [I]; need [A-1] [I] = need [A-1] [I] + request [I]; goto start;} printf ("\ n safe! Can be allocated to P % d process! \ N ", a); // printf (" \ n resource possession: \ n "); for (I = 0; I <n; I ++) {printf ("P % d resources allocated by processes:", I + 1 ); for (j = 0; j <m; j ++) printf ("% d", allocation [I] [J]); printf ("\ n ");} printf ("\ n Resource requirements: \ n"); for (I = 0; I <n; I ++) {printf ("Other resources required by P % d processes:", I + 1); For (j = 0; j <m; j ++) printf ("% d", need [I] [J]); printf ("\ n");} printf ("\ n resource data available :"); for (I = 0; I <m; I ++) printf ("% d", available [I]); printf ("\ n");} return 0 ;}