Petersons Algorithm in Process Synchronization


Coordinating the operations of processes that are running concurrently is the core concern of process synchronization, a basic issue in computer science. A crucial component of process synchronization, the mutual exclusion issue has a well-known solution in Peterson's Algorithm. This mutual exclusion algorithm, developed by Gary Peterson in 1981, is one of the most straightforward and popular ones. Peterson's Algorithm will be thoroughly examined in this article, including its description, justification for being accurate, benefits and drawbacks, comparison to other algorithms, applications, and conclusion.

Petersons Algorithm

  • Set turn to either 0 or 1, indicating which process can enter its critical section first.

  • Repeat indefinitely−

  • Set flag[i] to true, indicating that process i wants to enter its critical section.

  • Set turn to j, the other process index.

  • While flag[j] is true and turn equals j, wait.

  • Enter the critical section.

  • Set flag[i] to false, indicating that process i is done with its critical section.

  • Remainder section.

Description of the Algorithm

The mutual exclusion issue has a software-based solution known as Peterson's Algorithm, which seeks to guarantee that only one process is ever present in its critical region. Two shared variables, a flag array, and a turn variable, constitute the foundation of the algorithm. One flag is assigned to each process in the flag array, which contains Boolean values to represent whether or not a process is interested in accessing its crucial region. A turn variable is a number that indicates which process, in the event of a dispute, should go first.

A process calls the algorithm's two lock() and unlock() methods each time it wishes to enter or depart its crucial sector. The implementation of the lock() method is as follows −

void lock(int i) {
   flag[i] = true;
   turn = j; //j is the other process
   while (flag[j] && turn == j);
}

The unlock() method is a lot easier to use −

void unlock(int i) {
   flag[i] = false;
} 

The lock() method indicates that the calling process is interested in accessing its crucial section by first setting the flag of the calling process to true. If both processes want to access their crucial sections simultaneously, it then sets the turn variable to the index of the other process (j), signaling that the other process should proceed first. After that, the function enters a busy-waiting loop where it repeatedly checks to see if the other process's flag is true and if it is now its turn to reach the crucial area. The loop continues if one of these requirements is not met. After both requirements are satisfied, the loop ends and the calling procedure moves on to its crucial portion.

The calling process can leave its crucial area and no longer be interested in entering it by using the unlock() method to simply change its flag to false.

Syntax

int turn = 0;          // shared variable
bool flag[2] = {false, false}; // shared variable

Process 0:
while (true) {
   flag[0] = true;
   turn = 1;
   while (flag[1] && turn == 1) {} // busy wait
   // critical section
   flag[0] = false;
   // remainder section
}

Process 1:
while (true) {
   flag[1] = true;
   turn = 0;
   while (flag[0] && turn == 0) {} // busy wait
   // critical section
   flag[1] = false;
   // remainder section
}

Correctness of the Proof

The mutual exclusion issue has a valid solution in Peterson's algorithm, which meets the criteria listed below −

Mutual Exclusion

Just one process may ever be at its critical section at any one moment.

Progress

One of those processes will ultimately enter its critical section if no processes are currently in its critical sections and any number of processes wish to do so.

Bounded Waiting

There is a limit on how frequently other processes can stop a process from accessing its crucial phase.

Invariants, or characteristics that hold true before, during, and after the execution of the algorithm, are used to demonstrate the accuracy of Peterson's Algorithm. The proof incorporates the following invariants −

  • A process’s flag is true if it wants to access its vital section.

  • A process's flag is false if it has no desire to enter its crucial part.

  • A process's turn variable will equal its index if it is in its critical section.

These invariants can be used to demonstrate that the mutual exclusion property is valid since the busy-waiting loop requires at least one processor to wait until the other has completed running if two processes attempt to enter their crucial sections simultaneously. The progress property is true because the turn variable guarantees that at least one process will always be able to enter its critical section, thus even if no processes are in their critical sections and one or more of them wish to enter them, ultimately one of them will succeed. The busy-waiting loop ensures that each process will ultimately get a turn to access its crucial section, even if other processes are also interested in doing so, which is why the bounded waiting property is valid.

Different Approaches

A well-known remedy for the critical section issue in process synchronization is Peterson's Algorithm. It is utilized to make sure that just one process at a time may access a shared resource. Peterson's Algorithm has several versions that vary in how they are implemented but all adhere to the same fundamental idea.

Here are three typical methods for putting Peterson's algorithm into practise −

Approach 1: Using Flags

Each process in this method possesses a boolean flag that indicates if it want access to the shared resource. This is how the algorithm operates −

boolean flag[2] = {false, false};
int turn = 0;

/* Process 0 */
flag[0] = true;
turn = 1;
while (flag[1] && turn == 1);
/* critical section */
flag[0] = false;

/* Process 1 */
flag[1] = true;
turn = 0;
while (flag[0] && turn == 0);
/* critical section */
flag[1] = false;

This approach uses an array of boolean variables called flag to indicate whether a process wants to access the crucial area or not. The procedure that enters the critical region first is determined by the integer variable turn. The algorithm makes sure that if one process wishes to enter, the other process must wait until the turn is passed, preventing both processes from entering the vital part at once.

Approach 2: Using only the turn variable

In this method, the single variable utilized to determine which process may access the crucial part is called turn. This is how the algorithm operates −

int turn = 0;

/* Process 0 */
turn = 1;
while (turn == 1);
/* critical section */
turn = 1;

/* Process 1 */
turn = 0;
while (turn == 0);
/* critical section */
turn = 0;

The variable turn is utilized in this implementation to choose which process has access to the crucial part. The process can access the crucial section if turn is equivalent to the process ID. The process must wait until it is its turn if the turn is not identical to the process ID.

Approach 3: Utilizing a lock variable

This method uses a lock variable to show whether or not the crucial portion is locked. This is how the algorithm operates −

boolean lock = false;

/* Process 0 */
while (lock);
lock = true;
/* critical section */
lock = false;

/* Process 1 */
while (lock);
lock = true;
/* critical section */
lock = false;

In this implementation, the crucial section's lock status is shown by the variable lock. The crucial section is locked and the process must wait until it turns false if lock is equal to true. The process can access the crucial region and lock it if lock is set to true if lock is equal to false. When the essential part has been completed, the procedure unlocks it by setting lock to false.

Applications

Several computer science fields, notably operating systems and distributed systems, make use of Peterson's Algorithm. In crucial portions of code, such as file system operations, network connectivity, and shared memory access, the technique can be used to guarantee mutual exclusion. In distributed systems, such as those with distributed databases and message queues, the technique may also be used to coordinate access to shared resources.

Conclusion

In conclusion, Peterson's Algorithm is a well-known and still-used approach to the mutual exclusion issue. The method is straightforward and simple to comprehend, which makes it a desirable option for tiny systems. The algorithm has a few drawbacks, too, including a propensity for busy waiting and a reliance on common variables. Notwithstanding these drawbacks, Peterson's Algorithm has several uses in computer science, especially in operating systems and distributed systems. Overall, Peterson's Algorithm marks a significant turning point in the development of process synchronization and continues to be an effective method for guaranteeing mutual exclusion in contemporary computing systems.

Updated on: 19-Jul-2023

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements