- OS - Home
- OS - Overview
- OS - History
- OS - Evolution
- OS - Functions
- 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
- Process Suspension and Process Switching
- Process States and the Machine Cycle
- Inter Process Communication (IPC)
- Context Switching
- Threads
- Types of Threading
- Multi-threading
- System Calls
- 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
- Mutual Exclusion Using Interrupt Disabling
- 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
- Classical Synchronization Problems
- Dining Philosophers Problem
- Producer Consumer Problem
- Sleeping Barber Problem
- Reader Writer Problem
- OS Deadlock
- Introduction to Deadlock
- Conditions for Deadlock
- Deadlock Handling
- Deadlock Prevention
- Deadlock Avoidance (Banker's Algorithm)
- Deadlock Detection and Recovery
- Deadlock Ignorance
- Resource Allocation Graph
- Livelock
- Memory Management
- Memory Management
- Logical and Physical Address
- Contiguous Memory Allocation
- Non-Contiguous Memory Allocation
- First Fit Algorithm
- Next Fit Algorithm
- Best Fit Algorithm
- Worst Fit Algorithm
- Buffering
- Fragmentation
- Compaction
- Virtual Memory
- Segmentation
- Buddy System
- Slab Allocation
- Overlays
- Free Space Management
- Locality of Reference
- 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
- I/O Programmed
- I/O Interrupt-Initiated
- Direct Memory Access
- 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 - Classical Synchronization Problems
There are some classical synchronization problems that are used to illustrate the challenges of process synchronization and inter-process communication (IPC) in an operating system. These problems help in understanding how to manage concurrent processes and ensure data consistency across multiple entities (processes or threads in the cases of OS)
Here are some of the most well-known classical synchronization problems −
Dining Philosophers Problem
In the Dining Philosophers Problem, there are certain number of philosophers sitting around a circular table. Each philosopher have two states, thinking and eating. Between each pair of philosophers, there is a single cutlery.
To start eating, a philosopher needs access to both the cutlery on their left and right. Our task is to design a protocol that ensures that no deadlock and no starvation in the system.
The image below illustrates the Dining Philosophers Problem −
Solution
To solve this problem, we can use semaphores to represent the cutleries. Each philosopher will follow these rules:
- The cutleries are represented as binary semaphores initialized to 1 (available).
- A philosopher must acquire both the left and right cutlery before eating.
- After eating, the philosopher releases both the left and right cutlery.
The pseudo code for the philosopher's behavior can be represented as follows −
semaphore fork[3] = {1, 1, 1}; // Three forks
semaphore spoon[3] = {1, 1, 1}; // Three spoons
void philosopher(int i) {
while (true) {
think(); // Philosopher is thinking
// Pick up fork and spoon
wait(fork[i]); // Pick up fork
wait(spoon[i]); // Pick up spoon
eat(); // Philosopher is eating
// Put down fork and spoon
signal(spoon[i]); // Put down spoon
signal(fork[i]); // Put down fork
}
}
Producer Consumer Problem
The Producer Consumer Problem is also known as the Bounded Buffer Problem. It involves two types of processes, the producer process and the consumer process, which share a common, fixed-size buffer used as a queue.
The producer's job is to generate data, put it into the buffer, and start again. At the same time, the consumer is consuming the data (i.e., removing it from the buffer), one piece at a time.
The image below illustrates the Producer Consumer Problem −
The task is to make sure that the producer won't try to add data into the buffer if it's full and that the consumer won't try to remove data from an empty buffer.
Solution
To solve this problem, we can use semaphores to keep track of the number of empty and full slots in the buffer. The empty semaphore counts the number of empty slots, while the full semaphore counts the number of full slots. A mutex is used to ensure mutual exclusion when accessing the buffer.
semaphore empty = N; // Number of empty slots in the buffer semaphore full = 0; // Number of full slots in the buffer semaphore mutex = 1; // Mutex for critical section
The producer will have to follow these steps −
void producer() {
while (true) {
// Produce an item
item = produce_item();
wait(empty); // Decrement empty count
wait(mutex); // Enter critical section
// Add the item to the buffer
add_item_to_buffer(item);
signal(mutex); // Leave critical section
signal(full); // Increment full count
}
}
The consumer will have to follow these steps −
void consumer() {
while (true) {
wait(full); // Decrement full count
wait(mutex); // Enter critical section
// Remove an item from the buffer
item = remove_item_from_buffer();
signal(mutex); // Leave critical section
signal(empty); // Increment empty count
// Consume the item
consume_item(item);
}
}
Reader Writer Problem
In the Reader Writer Problem, there are two types of processes: readers and writers. Readers can read the data at the same time without any issues, but for writers, they need exclusive access to the data to prevent inconsistencies. Our task is to design a system that allows multiple readers to read simultaneously but when writers are writing, no other readers or writers can access the data.
Solution
To solve this problem, we again use semaphores. We will use a mutex to protect the count of readers and a semaphore to control access to the shared resource. The writeBlock semaphore will ensure that only one writer can access the resource at a time.
semaphore mutex = 1; // Mutex for protecting read_count semaphore writeBlock = 1; // Semaphore for controlling access to the resource int read_count = 0; // Number of active readers
The pseudocode for the reader process is as follows −
void reader() {
wait(mutex);
read_count++;
if (read_count == 1) {
wait(writeBlock); // first reader locks out writers
}
signal(mutex);
// critical section (reading)
read_data();
wait(mutex);
read_count--;
if (read_count == 0) {
signal(writeBlock); // last reader releases writers
}
signal(mutex);
}
The pseudocode for the writer process is as follows −
void writer() {
wait(writeBlock); // acquire exclusive access for writing
// critical section (writing)
write_data();
signal(writeBlock); // release exclusive access
}
Sleeping Barber Problem
In the Sleeping Barber Problem, there is a barber shop with one barber, one barber chair, and a waiting room with N chairs.
- When there is no customer, the barber sleeps in the barber chair.
- When a customer arrives, they either wake up the barber if he is sleeping or sit in an empty chair in the waiting room if the barber is busy.
- If there are no empty chairs in the waiting room, the customer will leave the shop.
The image below illustrates the Sleeping Barber Problem −
Solution
To solve this problem, we can use following semaphores −
- waitingRoom − This semaphore keeps the count of available chairs in the waiting room.
- barberChair − A binary semaphore to indicate whether the barber chair is occupied or not. It is initialized to 1 (available).
- barberSleep − This also a binary semaphore used to put the barber to sleep when there are no customers. It is initialized to 0 (sleeping).
// Barber behavior
void barber() {
while (true) {
wait(barberSleep); // Sleep if there are no customers
wait(barberChair); // Acquire the barber chair
// Cut hair
signal(barberChair); // Release the barber chair
}
}
// Customer behavior
void customer() {
if (wait(waitingRoom) == 0) { // Check for available chairs
signal(waitingRoom); // Leave if no chairs are available
return;
}
wait(barberChair); // Acquire the barber chair
signal(barberSleep); // Wake up the barber if sleeping
// Get hair cut
signal(barberChair); // Release the barber chair
}
Conclusion
In real life, we often encounter situations where multiple entities need to access shared resources concurrently, such as waiting in queue for a service or sharing a common facility. Such situations can also occur in operating systems where multiple processes and threads are running simultaneously while sharing resources like memory, files, and devices. The classical synchronization problems discussed above will help us to understand how to deal with such situations without causing deadlocks and starvation.