- OS - Home
- OS - Needs
- OS - Overview
- OS - History
- OS - Components
- OS - Structure
- OS - Architecture
- OS - Services
- OS - Properties
- Process Management
- Processes in Operating System
- States of a Process
- Process Schedulers
- Process Control Block
- Operations on Processes
- Inter Process Communication (IPC)
- Context Switching
- Multi-threading
- Scheduling Algorithms
- Process Scheduling
- Types of Scheduling
- Scheduling Algorithms Overview
- FCFS Scheduling Algorithm
- SJF Scheduling Algorithm
- Round Robin Scheduling Algorithm
- HRRN Scheduling Algorithm
- Priority Scheduling Algorithm
- Multilevel Queue Scheduling
- Lottery Scheduling Algorithm
- Starvation and Aging
- Turn Around Time & Waiting Time
- Burst Time in SJF Scheduling
- Process Synchronization
- Process Synchronization
- Solutions For Process Synchronization
- Hardware-Based Solution
- Software-Based Solution
- Critical Section Problem
- Critical Section Synchronization
- Mutual Exclusion Synchronization
- Peterson's Algorithm
- Dekker's Algorithm
- Bakery Algorithm
- Semaphores
- Binary Semaphores
- Counting Semaphores
- Mutex
- Turn Variable
- Bounded Buffer Problem
- Reader Writer Locks
- Test and Set Lock
- Monitors
- Sleep and Wake
- Race Condition
- OS Deadlock
- Introduction to Deadlock
- Conditions for Deadlock
- Deadlock Handling
- Deadlock Prevention
- Deadlock Avoidance (Banker's Algorithm)
- Deadlock Detection and Recovery
- Deadlock Ignorance
- Memory Management
- Memory Management
- Contiguous Memory Allocation
- Non-Contiguous Memory Allocation
- First Fit Algorithm
- Next Fit Algorithm
- Best Fit Algorithm
- Worst Fit Algorithm
- Fragmentation
- Virtual Memory
- Segmentation
- Buddy System
- Slab Allocation
- Overlays
- Paging and Page Replacement
- Paging
- Demand Paging
- Page Table
- Page Replacement Algorithms
- Optimal Page Replacement Algorithm
- Belady's Anomaly
- Thrashing
- Storage and File Management
- File Systems
- File Attributes
- Structures of Directory
- Linked Index Allocation
- Indexed Allocation
- Disk Scheduling Algorithms
- FCFS Disk Scheduling
- SSTF Disk Scheduling
- SCAN Disk Scheduling
- LOOK Disk Scheduling
- I/O Systems
- I/O Hardware
- I/O Software
- OS Types
- OS - Types
- OS - Batch Processing
- OS - Multiprocessing
- OS - Hybrid
- OS - Monolithic
- OS - Zephyr
- OS - Nix
- OS - Linux
- OS - Blackberry
- OS - Garuda
- OS - Tails
- OS - Clustered
- OS - Haiku
- OS - AIX
- OS - Solus
- OS - Tizen
- OS - Bharat
- OS - Fire
- OS - Bliss
- OS - VxWorks
- OS - Embedded
- OS - Single User
- Miscellaneous Topics
- OS - Security
- OS Questions Answers
- OS - Questions Answers
- OS Useful Resources
- OS - Quick Guide
- OS - Useful Resources
- OS - Discussion
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
- Steps of the Bakery Algorithm
- Implementation of the Bakery Algorithm
- Advantages of the Bakery Algorithm
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.