![]() |
VOOZH | about |
A software-based solution is a method of solving problems using software programs instead of additional hardware. In operating systems, it means handling tasks like security, error detection, or resource management through software techniques, making the system more flexible and cost-effective.
Various software solutions to the Critical Section Problem are:
This is a simple synchronization method that works in user mode and is a busy-waiting solution for multiple processes. It uses a lock variable, lock to manage access to the critical section.
The lock variable can have two values:
When a process wants to enter the critical section, it first checks the lock variable:
Entry Section
While (lock! = 0);
Lock = 1;
//Critical Section
Exit Section
Lock =0;
Initially, the lock variable is set to 0. When a process wants to enter the critical section, it goes through an entry section and checks a condition in a while loop.
When the process finishes its work in the critical section, it goes through the exit section and sets the lock back to 0, making the critical section available for other processes.
Lock Variable fails to satisfy Bounded Wait. This may be because a process can enter CS multiple times successively while other processes are waiting for their turn to enter CS.
Read more about Lock Variable Synchronization Mechanism.
The Turn Variable or Strict Alternation Approach is a simple software mechanism used in user mode. It is a busy-waiting solution designed specifically for two processes.
This method works only for two processes and is not suitable for systems with more than two processes.
For Process Pi: | For Process Pj: |
|---|
A process can enter the critical section only when the turn variable matches the process's ID (PID). The turn variable can have only two values: i or j.
This ensures that the two processes alternate access to the critical section.
Strict Alternation never guarantees progress.
To handle the problem of Critical Section (CS) Peterson gave an algorithm with a bounded waiting.
Suppose there are N processes (P1, P2, … PN) and each of them at some point need to enter the Critical Section.
A flag[] array of size N is maintained which is by default false and whenever a process need to enter the critical section it has to set its flag as true, i.e. suppose Pi wants to enter so it will set flag[i]=TRUE.
There is another variable called turn which indicates the process number which is currently to enter into the CS. The process that enters into the CS while exiting would change the turn to another number from among the list of ready processes.
var flag[]: array [0..1] of boolean;
turn: 0..1;
%flag[k] means that process[k] is interested in the critical section
flag[0] := FALSE;
flag[1] := FALSE;
turn := random(0..1)
After initialization, each process, which is called process i in the code (the other process is process j), runs the following code:
repeat
flag[i] := TRUE;
turn := j;
while (flag[j] and turn=j) do no-op;
CRITICAL SECTION
flag[i] := FALSE;
REMAINDER SECTION
until FALSE;
Information common to both processes:
turn = 0
flag[0] = FALSE
flag[1] = FALSE
EXAMPLE | |
Process 0 | Process 1 |
i = 0, j = 1 | i = 1, j = 0 |
flag[0] := TRUE turn := 1 check (flag[1] = TRUE and turn = 1) - Condition is false because flag[1] = FALSE - Since condition is false, no waiting in while loop - Enter the critical section - Process 0 happens to lose the processor | |
flag[1] := TRUE turn := 0 check (flag[0] = TRUE and turn = 0) - Since condition is true, it keeps busy waiting until it loses the processor | |
- Process 0 resumes and continues until it finishes in the critical section - Leave critical section flag[0] := FALSE - Start executing the remainder (anything else a process does besides using the critical section) - Process 0 happens to lose the processor | |
check (flag[0] = TRUE and turn = 0) - This condition fails because flag[0] = FALSE - No more busy waiting - Enter the critical section | |
Read more about Peterson's Solution.
Dekker’s Algorithm is one of the earliest known solutions to the Critical Section (CS) problem. It ensures mutual exclusion, progress, and bounded waiting for two processes trying to access a shared resource. Unlike Peterson’s, it was designed before modern atomic instructions and uses shared variables with busy waiting.
Suppose there are two processes (P0 and P1). Each process uses a flag[] array and a shared variable turn.
Initialization:
var flag[]: array [0..1] of boolean;
turn: 0..1;
flag[0] := FALSE;
flag[1] := FALSE;
turn := 0
i):Let the other process be j.
repeat
flag[i] := TRUE;
while flag[j] do
if turn = j then
begin
flag[i] := FALSE;
while turn = j do
no-op; % wait
flag[i] := TRUE;
end;
CRITICAL SECTION
turn := j;
flag[i] := FALSE;
REMAINDER SECTION
until FALSE;
1. Intention to enter CS: Each process sets its flag[i] := TRUE to indicate that it wants to enter the Critical Section (CS).
2. Check if the other process wants to enter: If the other process (j) has also set flag[j] = TRUE, then both want to enter at the same time.
3. Turn mechanism
turn variable decides which process gets priority.turn = j), the current process backs off by setting flag[i] := FALSE and waits until turn ≠ j.flag[i] := TRUE and tries to enter.4. Critical Section (CS): Once the conditions are satisfied, the process enters the CS safely, ensuring only one process executes inside CS at a time.
5. Exit section: After finishing CS, the process
turn := j.flag[i] := FALSE.6. Remainder Section: The process executes its normal code (non-critical part) and then repeats the cycle.
Before this many
Final and completed Solution: Idea is to use favoured thread notion to determine entry to the critical section. Favoured thread alternates between the thread providing mutual exclusion and avoiding deadlock, indefinite postponement, or lockstep synchronization.
This version guarantees a complete solution to the critical solution problem.
Read more about Dekker's Algorithm.