N process Peterson algorithm
Last Updated :
22 Nov, 2024
In any operating system, it is important to control how different processes run at the same time. When multiple processes are working, we have to control which process can change important information such as the variables in a program at that moment. This makes it possible to get errors or unexpected results in case it has not been done.
Such interference can be prevented by certain techniques, and one of the techniques is Peterson’s Algorithm. Another very familiar example of the critical section problem is the Producer-Consumer problem. If the processes do not properly synchronize, then it may result in something undesirable like a wrong count of items in the buffer. It prevents these problems by Peterson’s algorithm by controlling the access of various critical sections to different processes.
Description
Peterson’s solution is a software-based solution to race conditions or critical-section problems. It is usually not implemented in modern computers, but this solution provides a basic algorithmic way to solve the critical section problem. We will mainly consider the Producer-Consumer problem throughout this article. At first, this algorithm was presented easily where there was an aim to establish synchronization between only 2 processes. So it can be further expanded to consider synchronization among N processes by making a small change to it.
Peterson’s Solution to 2 Processes
Let’s consider 2 processes working parallel in an operating system. These processes modify the same variables, hence they both have a risk of entering a race condition. We consider that each process has a remainder section where they are not modifying such variables which can lead to race conditions and another section named a critical section where the processes may have a chance to enter the race condition. So a basic Peterson Algorithm for such cases is given below.
Step-1: Let’s consider the two processes being named P0 and P1. So we can switch between these two processes using a simple formula i.e. 1-<base of process>. To change the pointer to P0 from P1, it should be changed by the formula as idx = 1-1 (base of P1) = 0. Hence, in this way at any time idx will be either pointing to P1 or P0.
Step-2: This algorithm requires two data items to be shared between processes.
int turn;
This variable indicates whose turn is it to execute the critical section part of its program. If turn == 1, then it’s the turn for P1 to enter the critical section area.
boolean flag[2];
This array indicates that if a process is ready to enter its critical section or not. flag[0]==true means P0 is ready to execute its critical section part of the program.
Step-3: The main part of this algorithm is given below. The process if want to enter the critical section part of the program then they have to perform two things as follows.
- Set the flag[idx] = true. If P1 want to enter than it should set flag[1]=true.
- Set turn = 1-idx,i.e. if P1 wants to enter then it should set turn in terms of another process since it implies that if another process wishes to enter the critical section part can do so after P1 has executed its part.
Step-4 : The algorithm is presented as follows. Any process is inhibited to enter the critical section of the program till both of the following things happens.
1) if flag[1-idx]==true
2) if turn == 1-idx.
Now till both the above conditions are true the process waits in a while loop doing nothing and if any of the condition becomes non-true process enter the critical section and the next process (i.e. 1-idx) is waiting in the loop to execute the critical section part if wanted. This also guarantees that no two processes are executing the critical section part at the same time.
Pseudo-Code:
Hence, the Pseudo-Code of the algorithm can be given as follows.
idx=0;
do{
// preparing to enter the critical section part
flag[idx] = TRUE;
turn = 1-idx;
while(flag[1-idx]==TRUE and turn == 1-idx)
// checking the two variables continuously. This is a waste of time.
;
// continues in the loop till chance cames
/*
Critical section part
*/
flag[idx] = FALSE;
/*
Remainder section part
*/
}
Hence, in this way, there exists synchronization between two processes. The above algorithm guarantees that there always exists mutual exclusion and synchronization between the two processes.
Peterson’s algorithm for N-Process
This algorithm assumes the same data structure as discussed above. The only modification it has is that it is using an N size array and variable turn can have values from 0 to N-1. There is also a very large change in this algorithm since in the above algorithm in the while condition we are continuously referring to the turn variable to contain the complementary process’s number. But in this algorithm, it is not the case because there are more than 2 Processes.
Implementation
The idea to implement the above algorithm is given below.
Step-1 : Let’s consider a queue of size N for N processes to be placed in it. Now suppose we write an algorithm as Each process pushes itself in the queue to come at the end of the queue at some time, and then they will be allowed to execute their critical section and leave the queue. In this way, we can guarantee that each process is allowed to execute their critical section once they enter the queue and reaches to its end (front). Till the process reaches the front it should have to wait since there can be two conditions happening at that moment.
- Either some processes might be at the next index in the queue and are waiting for someone else.
- Or if any back process (which enters the queue late) doesn’t move to the current process’s location. (This means that the back process checks that the front is emptied and wants to push the queue forwards.)
The first case is straight clear, but there is a trick (or we can say an idea) inside the second one. You will get it clear after reading 2nd point.
Step-2 : The data structure for the algorithm is the same as for 2 processes one, but now the Turn becomes an array of size N, and also the Flag is the array of size N.
Flag[PID]
// has size N and PID always ranges from 0---N-1 since there are N processes.
To indicate the position at which the PIDth process is in the queue.
Turn[i] = PID // has size N
- To mark that till now no process says that it is at position i (since if any process says like that then it means that there is a back push from later processes and hence the current process should change its position).
- Back-Push happens since some process which enters late in the queue should be given place to enter and so there exists a push for rest process to the front of the queue. Back-push arises since the system works in a multiprocessor environment, concurrently executing processes.
- Also, slowly the size of the queue may decrease since some processes after executing their critical section may be terminated or leave the queue or enter another one for another critical section.
Hence, the pseudo-code for N process Peterson’s algorithm is explained below.
- We will make two functions named lock() and unlock(). In the lock() function the process waits till it reaches the end of the queue and in unlock() function it marks the exit from the queue.
- The execution of the critical section takes place when the process is at the end of the queue i.e. between the lock and unlock methods.
- The two methods are described below as follows.
LOCK( Process PID){
for( int i = 0;i<N;++i){
//Looping through position from 0 to end (N) of queue.
Turn[i]=PID;
// Tells that PID process is at ith position.
Flag[PID]=i;
// Tells that till now there is no back push
while((for all k != PID, Flag[k]<i) or (Turn[i] != PID))
;
//Wait till either there is no process
//at the top of queue or there is a back push.
}
}
UNLOCK(Process PID) {
if (/* condition where process exits or terminates */) {
Flag[PID] = -1; // Process exists or terminates, or moves to another queue
}
else {
Flag[PID] = 0; // Process enters the first position in the queue
}
}
Hence, the Pseudo-Code for the above algorithm is given below.
LOCK( Process PID){
for( int i = 0;i<N;++i){
Turn[i]=PID;
Flag[PID]=i;
while((for all k != PID, Flag[k]<i) or (Turn[i] != PID))
;
}
}
/* Critical Section */
UNLOCK(Process PID) {
if (/* condition where process exits or terminates */) {
Flag[PID] = -1;
// Process exists or terminates, or moves to another queue
}
else {
Flag[PID] = 0;
// Process enters the first position in the queue
}
}
Conclusion
It can be clearly seen that the above algorithm obeys all the rules to be satisfied for synchronized and concurrent processes in any multi-Processor environment. Hence, we are able to get knowledge about how Peterson’s algorithm works for N-Processes.
Similar Reads
Peterson's Algorithm in Process Synchronization
Peterson's Algorithm is a classic solution to the critical section problem in process synchronization. It ensures mutual exclusion meaning only one process can access the critical section at a time and avoids race conditions. The algorithm uses two shared variables to manage the turn-taking mechanis
15+ min read
Prim's Algorithm in C++
Prim's Algorithm is a greedy algorithm that is used to find the Minimum Spanning Tree (MST) for a weighted, undirected graph. MST is a subset of the graph's edges that connects all vertices together without any cycles and with the minimum possible total edge weight In this article, we will learn the
6 min read
What is Peterson Graph?
A graph is a collection of points, called vertices (or nodes), and a set of edges (or arcs) that connect pairs of vertices. There are various types of graphs such as: Directed Graph (Digraph)Undirected GraphWeighted GraphComplete GraphBipartite GraphTreeCyclic GraphAcyclic GraphPeterson Graph is one
4 min read
CSES Solutions - Weird Algorithm
Consider an algorithm that takes as input a positive integer N. If N is even, the algorithm divides it by two, and if N is odd, the algorithm multiplies it by three and adds one. The algorithm repeats this, until N is one. Your task is to simulate the execution of the algorithm for a given value of
4 min read
Trial division Algorithm for Prime Factorization
In this article, the trial division method to check whether a number is a prime or not is discussed. Given a number N, the task is to check whether the number is prime or not. Examples: Input: N = 433 Output: Prime Explanation: The only factors of 433 are 1 and 433. Therefore, it is a prime. Input:
7 min read
Boyer-Moore Majority Voting Algorithm
The Boyer-Moore voting algorithm is one of the popular optimal algorithms which is used to find the majority element among the given elements that have more than N/ 2 occurrences. This works perfectly fine for finding the majority element which takes 2 traversals over the given elements, which works
7 min read
Peterson's Algorithm for Mutual Exclusion | Set 1 (Basic C implementation)
Problem: Given 2 processes i and j, you need to write a program that can guarantee mutual exclusion between the two without any additional hardware support. Solution: There can be multiple ways to solve this problem, but most of them require additional hardware support. The simplest and the most pop
6 min read
JavaScript Program for Sum of n Terms of Arithmetic Progression
Arithmetic progression is a sequence of numbers in which the difference between any two consecutive terms is always equal. This difference between any two consecutive terms is known as a common difference and it can be positive, negative, or zero. Below are the approaches to find Sum of n terms in A
4 min read
JavaScript Program for Sum of n Terms of Harmonic Progression
One can find the sum of n terms of Harmonic Progression using JavaScript. Harmonic Progression is a sequence of real numbers in which each term is reciprocal of Arithmetic Progression. There are different approaches to finding the sum of n terms of Harmonic Progression which are discussed below: Tab
3 min read
Minimum cost to reach the last stone
Given an array arr[] of size n, where arr[i] denotes the height of stone i. Geek starts from stone 0 and from stone i, he can jump to stones i + 1, i + 2, ... i + k. The cost for jumping from stone i to stone j is abs(arr[i] - arr[j]). Find the minimum cost for Geek to reach the last stone. Examples
15+ min read