Operating System - Bakery Algorithm for Process Synchronization



The Bakery Algorithm is a classic software-based solution for achieving mutual exclusion and synchronization between multiple processes. It was proposed by Leslie Lamport in 1974. The algorithm is inspired by the way customers were given numbers in a bakery and served in the order of their numbers.

Read this chapter to understand how the Bakery Algorithm works and how it implement it to ensure process synchronization.

The Bakery Algorithm

The idea behind the Bakery Algorithm is to assign a unique ticket number to each process that wants to enter its critical section. The ticket number indicates the order in which the processes will be allowed to enter their critical sections. The process with the lowest ticket number is allowed to enter its critical section first. Sometimes if two processes have the same ticket number, then the process with the lower process ID is given priority.

To implement the Bakery Algorithm, we use two shared variables −

  • choosing[i](boolean): Stores whether process i is in the process of choosing a number.
  • number[i](integer): holds the number assigned to process i, This is the token to enter the critical section.

Let's get into the steps of implementing the Bakery Algorithm.

Steps of the Bakery Algorithm

The following are the steps or processes for the Bakery Algorithm −

  • Set the choosing[i] to true, indicating that process i is in the process of choosing a ticket number.
  • Now, set the number[i] to 1 plus the maximum ticket number among all processes.
  • Then, set choosing[i] to false, indicating that process i has finished choosing its ticket number.
  • For each process j, wait until choosing[j] is false (i.e., process j has finished choosing its ticket number).
  • For each process j, wait until either number[j] is 0 (i.e., process j is not interested in entering its critical section) or (number[j], j) is greater than (number[i], i) (i.e., process j has a higher ticket number or the same ticket number but a higher process ID).
  • Enter the critical section.
  • Set number[i] to 0, indicating that process i has finished its critical section.
  • Remainder section.

Implementation of the Bakery Algorithm

The section below implements the Bakery Algorithm in C++.

#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
#include <atomic>

using namespace std;
const int NUM_PROCESSES = 5;
atomic<bool> choosing[NUM_PROCESSES];
atomic<int> number[NUM_PROCESSES];

void bakery_process(int i) {
    for (int iter = 0; iter < 5; iter++) {
        // Choosing a number
        choosing[i] = true;
        number[i] = 1 + *max_element(number, number + NUM_PROCESSES);
        choosing[i] = false;

        // Waiting for other processes
        for (int j = 0; j < NUM_PROCESSES; j++) {
            while (choosing[j]);
            while (number[j] != 0 && (number[j] < number[i] || (number[j] == number[i] && j < i)));
        }

        // Critical Section
        cout << "Process " << i << " is in its critical section." << endl;

        // Exit Section
        number[i] = 0;

        // Remainder Section
        cout << "Process " << i << " is in its remainder section." << endl;
    }
}

int main() {
    vector<thread> processes;
    for (int i = 0; i < NUM_PROCESSES; i++) {
        choosing[i] = false;
        number[i] = 0;
    }
    for (int i = 0; i < NUM_PROCESSES; i++) {
        processes.push_back(thread(bakery_process, i));
    }
    for (auto &process : processes) {
        process.join();
    }
    return 0;
}

The output of the above code will be −

Process 0 is in its critical section.
Process 0 is in its remainder section.
Process 1 is in its critical section.
Process 1 is in its remainder section.
...

Advantages of the Bakery Algorithm

The Bakery Algorithm is preferred in most situations due to the following advantages −

  • No Starvation − It is garanteed that every process will eventually get a chance to enter its critical section. So there is no possibility of starvation.
  • Fairness − The algorithm ensures that processes are served in the order of their ticket numbers. This ensures fairness among processes.
  • Scalability − The Bakery Algorithm can be implemented for any number of processes, making it scalable for systems with varying numbers of processes.
  • Simplicity − The algorithm is relatively simple to understand and implement.

Conclusion

The Bakery Algorithm is a token based solution for achieving mutual exclusion and synchronization between multiple processes. The idea is to assign a unique token number every process that wants to enter a critical section, and the process with the lowest token number is allowed to enter its critical section first. The algorithm ensures no starvation, fairness, scalability, and simplicity. So this algorithm is widely used in operating systems for process synchronization.

Advertisements