• Operating System Video Tutorials

Operating System - Peterson Solution in Process Synchronization



Peterson Solution in Process Synchronization

Coordinating the operations of concurrently running processes synchronization, a key issue in computer science. A critical aspect of process synchronization is the mutual exclusion problem, for which Peterson's Algorithm offers a well-known solution.

Developed by Gary Peterson in 1981, this mutual exclusion algorithm is one of the most straightforward and popular methods. In this chapter, we will thoroughly examine Peterson's Algorithm, including its description, proof of correctness, advantages and disadvantages, comparison and other algorithms, applications, and conclusion.

Peterson's Algorithm

The following are the steps or processes for Peterson's Algorithm −

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

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

  • Set turn to j, the index of the other process.

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

  • Enter the critical section.

  • Set flag[i] to false, indicating that process i has finished its critical section.

  • Remainder section.

Description of the Algorithm

Peterson's Algorithm is a software-based solution to the mutual exclusion problem, ensuring that only one process is ever in its critical section at a time. the algorithm is based on two shared variables: a flag array and a turn variable.

Each process has an associated flag in the flag array, which contains Boolean values to indicate whether a process is interested in entering its critical section. The turn variable is a number that determines which process should proceed frost in case of a conflict.

A process invokes the algorithm's lock() and unlock() methods each time it wishes to enter or exit its critical section. 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 signals that the calling process wants to access its critical section by first setting its own flag to true. if both processes attempt to access their critical sections simultaneously, the method sets the turn variable to other process's index(j), indicating that the other process should proceed first.

Then,the method enters a busy-wait loop, repeatedly checking whether the other process's flag is true and if it's their turn to access the critical section. The loop continues as long as either condition is not me. Once both conditions are satisfied, the loop ends, and the calling process proceeds to its critical section.

The calling process can exit its critical section and indicate it no longer wants to enter by setting its flag to false using the unlock() method.

Example

The code implements Peterson's Algorithm for mutual exclusion. It uses two processes with flags and a turn variable to ensure only one process enters its critical section at a time, avoiding conflicts.

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

Peterson's Algorithm provides a valid solution to the mutual exclusion problem, meeting the following criteria −

  • Mutual Exclusion: Only one process can be in its critical section at any given time.
  • Progress: If no processes are currently in their critical sections and any number of processes wish to enter, one of those processes will eventually enter its critical section.
  • Bounded Waiting: There is a limit to how often other processes can prevent a process from accessing its critical section.

Invariants, which are characteristics that remain 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 processs flag is set to true when it wants to access its critical section.

  • A process's flag is set to false when it has no desire to enter its critical section.

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

These invariants demonstrates the validity of mutual exclusion property. The busy-waiting loop ensures that at least one processor attempt to enter their critical section simultaneously. The progress property is satisfied because the turn variable guarantees that at least one process will eventually enter its critical section.

Even if no processes are in their critical section and one or more wish to enter, one of them will succeed. The bounded waiting property is valid because the busy-waiting loop ensures that each process will eventually get a turn to access its critical section, even if other processes are also interested in doing so.

Different Approaches

Peterson's Algorithm is a well-known solution for the critical section problem in process synchronization. It ensures that only one process at a time can access a shared resource.

While there are several variations of Peterson's Algorithm with different implementations, they all at the same fundamental principle. Here are three common methods for implementing Peterson's Algorithm −

Using Flags

Each process in this method has a boolean flag that indicates whether it ants access to the shared resource. The algorithm operates as follows −

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 critical section. The process that enters the critical section first determined by the integer variable turn.

The algorithm ensures that if one process wants to enter, the other process must wait until the turn is passed, preventing both processes from entering the critical section simultaneously.

Using only the Turn Variable

In this method, the single variable turn is used to determine which process can access the critical section. The algorithm operates as follows −

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;

In this implementation, the turn variable is used to determine which process can access the critical section. If turn equals the process ID, the process must wait until it is its turn.

Utilizing a lock variable

This method uses a lock variable to indicate whether the critical section is locked. The algorithm operates as follows −

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 lock variable indicates the lock status of the critical section. If lock is true, the critical section is locked, and the process must wait until it turns false.

If lock is false, the process can access and lock the critical section by setting Lock to true. After completing the critical section, the process unlocks it by setting lock to false.

Applications

Peterson's Algorithm is used in several fields of computer science, particularly in operating systems and distributed systems. It ensures mutual exclusion in critical sections of code, such as file system operations, network connectivity, and shared memory access. In distributed systems, the algorithm can also be used to coordinate access to shared resources, like distributed databases and message queues.

Conclusion

In conclusion, Peterson's Algorithm is a well-known and still widely - used approach to the mutual exclusion problem. Its straightforward and easy-to-understand method makes it a desirable option for small systems. However, the algorithm has a few drawbacks, such as a tendency for busy waiting and reliance on shared variables.

Despite these drawbacks, Peterson's Algorithm has many applications in computer science, particularly in operating systems and distributed systems. Overall, Peterson's Algorithm represents a significant milestone in the development of process synchronization and remains an effective method for ensuring mutual exclusion in modern computing systems.

Advertisements