IPC and Deadlocks in Operating Systems
IPC and Deadlocks in Operating Systems
NotesNeo
Syllabus :
Inter-process Communication: Critical Section, Race Conditions, Mutual Exclusion,,
Semaphores, Event Counters, Monitors, Message Passing, Classical IPC Problems: The
Producer Consumer Problem, Reader Writer Problem, Dining Philosopher Problem etc.
Deadlocks: Definition, Necessary and sufficient conditions for Deadlock, Deadlock
Prevention, and Deadlock Avoidance: Banker’s algorithm, Deadlock detection and
Recovery.
Definition
Process synchronization in an operating system refers to the coordination of multiple
processes to ensure orderly execution and prevent conflicts when accessing shared
resources. It involves implementing mechanisms that allow processes to cooperate and
communicate effectively.
Importance
1. Data consistency: Synchronization ensures that shared data accessed by multiple
processes remain consistent and coherent.
2. Avoidance of race conditions: Race conditions occur when the outcome of a
program depends on the sequence or timing of concurrent process execution.
Synchronization mechanisms prevent race conditions by enforcing orderly access
to shared resources.
3. Deadlock and starvation prevention: Synchronization techniques help prevent
deadlock situations where processes are unable to proceed due to resource
contention. They also mitigate starvation, ensuring fair access to resources for all
processes.
4. Performance optimization: Efficient synchronization can improve system
performance by minimizing overhead and maximizing resource utilization.
1. Shared resources:
● When multiple processes access shared resources such as memory, files, or
hardware devices concurrently, synchronization is necessary to prevent data
corruption and maintain integrity.
● Example:
Consider a banking application with multiple concurrent transactions. If two
processes try to update the same account balance simultaneously without
synchronization, it could result in inconsistencies or incorrect balances.
Synchronization mechanisms ensure that only one process accesses the account
balance at a time, preventing such issues.
3. Mutual exclusion:
● In scenarios where only one process should access a critical section of code or a
shared resource at a time, mutual exclusion ensures that conflicting accesses do
not occur concurrently.
● Example:
Consider a printer shared by multiple processes. To avoid printing conflicts, only
one process should be allowed to access the printer at any given time.
Synchronization mechanisms such as mutex locks or semaphores enforce mutual
2
NotesNeo
exclusion, ensuring that only one process prints at a time while others wait their
turn.
Definition
● A critical section refers to the part of program where shared resources are
accessed by various cooperative processes. It is a part of the code that must be
executed atomically, meaning without interruption, to maintain data consistency
and integrity.
● Only one process should be allowed to execute within the critical section at any
given time to avoid inconsistencies or race conditions.
● Example: Consider multiple processes accessing a shared printer. The critical
section here would be the code that sends a print job to the printer. Only one
process should be allowed to access this critical section at any given time to avoid
conflicts.
Purpose
● The purpose of a critical section is to protect shared resources from concurrent
access by multiple processes or threads. By restricting access to the critical section
to only one entity at a time, the integrity of shared data is maintained, and race
conditions are prevented.
● Critical sections are essential for ensuring data consistency and avoiding conflicts
in concurrent programming environments.
3
NotesNeo
4. Shared Resources: Critical sections typically involve accessing shared variables,
data structures, or hardware devices that are shared among multiple processes or
threads.
4
NotesNeo
3. Resource Allocation: Multiple threads request access to a finite pool of resources.
Without proper locking mechanisms, two or more threads may be allocated the
same resource simultaneously, leading to resource contention or deadlock.
5
NotesNeo
6
NotesNeo
1.6 Semaphores
● Semaphore is a synchronization primitive variable that controls access to a shared
resource and coordinate the execution of multiple processes or threads.
● It was introduced by Edsger Dijkstra in the 1960s and is widely used in operating
systems and multi-threaded applications.
7
NotesNeo
● It acts as a hardware solution to the critical section problem, which involves
ensuring that only one process can enter a critical section at a time. The critical
section problem arises when multiple processes share variables and need to access
them in a coordinated manner.
Operations:
● Semaphores maintain an integer value that can be modified by two fundamental
operations: wait (also known as P or down operation) and signal (also known as V
or up operation).
1. Wait (P) Operation: This operation decrements the semaphore value. If the
semaphore value becomes negative, the process waits until it becomes
positive.
2. Signal (V) Operation: This operation increments the semaphore value. If
there are waiting processes, one of them is allowed to proceed.
Types of Semaphores:
1. Binary Semaphore: Can take only two values (0 or 1). Used for mutual exclusion
(e.g., ensuring only one process accesses a resource at a time).
2. Counting Semaphore: Can take any non-negative integer value. Used for
scenarios where multiple processes can access a resource up to a certain limit.
Advantages:
1. Synchronization: Semaphores ensure orderly access to shared resources,
preventing conflicts.
2. Deadlock Prevention: Properly designed semaphores can prevent deadlocks.
3. Process Coordination: Semaphores allow processes to coordinate their actions.
1. Binary Semaphores:
● Also known as mutex (mutual exclusion) or simply a lock, a binary semaphore can
take on only two values: 0 and 1. It is typically used to control access to a single
resource, allowing only one thread or process to access it at a time.
● Binary semaphores are often used to implement critical sections and ensure mutual
exclusion.
2. Counting Semaphores:
● Unlike binary semaphores, counting semaphores can take on multiple non-negative
integer values. They are used to control access to a finite number of identical
resources.
● Counting semaphores are commonly employed to limit the number of concurrent
accesses to a shared resource, such as a fixed-size buffer or a pool of worker
threads.
8
NotesNeo
integer value representing the count of events or the number of available
resources. It is used to coordinate synchronization among processes, especially in
scenarios where a fixed number of resources are available.
● Example: Suppose a system has a limited number of network connections. An event
counter keeps track of the available connections. Processes requesting a
connection decrement the counter, and when the counter reaches zero, further
requests are blocked until connections are released.
9
NotesNeo
wait for all tasks to complete by monitoring the value of the event counter
representing the number of tasks remaining.
1.8 Monitors
● A monitor is a high-level synchronization construct used in concurrent
programming to encapsulate shared data and the operations performed on that
data within a single programming language construct.
● The concept of monitors was introduced by Per Brinch Hansen in the 1970s.
Purpose:
Monitors manage access to shared resources (such as files or data) among multiple
processes. They ensure that only one process can use a resource at a time, preventing
conflicts and data corruption.
Implementation:
Monitors are typically implemented as programming language constructs, often in
object-oriented languages. They encapsulate a shared resource and provide access
through a set of procedures. These procedures ensure that only one process accesses the
resource simultaneously, while others wait until it becomes available.
Features:
1. Mutual Exclusion: Monitors enforce mutual exclusion, allowing only one process
inside the monitor at any given time.
2. Condition Variables: Monitors include condition variables and procedures.
Processes can wait on condition variables (using wait()) and signal other processes
(using signal()) when a condition is met.
3. Data Encapsulation: Monitors encapsulate shared resources and relevant
procedures, making synchronization easier to reason about.
4. Abstraction: Monitors hide low-level synchronization details, such as semaphores or
locks, simplifying concurrent program implementation.
Limitations:
1. Monitors may be less efficient than lower-level primitives due to their higher-level
abstraction.
2. Not suitable for all synchronization problems; sometimes lower-level primitives are
needed for optimal performance.
10
NotesNeo
● Inter-process communication involves exchanging information between multiple
threads within one or more processes or programs.
Importance
IPC is crucial for enabling cooperation and coordination among processes running
concurrently on a computer system. Some key reasons why IPC is important include:
1. Cooperation: IPC enables processes to work together towards common goals by
exchanging information, coordinating actions, and synchronizing their activities.
This cooperation is essential for implementing complex systems and distributed
applications.
2. Resource Sharing: IPC allows processes to share resources such as data, files,
memory, and hardware devices. This enables efficient resource utilization and
improves system scalability.
3. Concurrency: IPC facilitates communication and synchronization between
concurrent processes or threads, allowing them to interact without interfering with
each other's execution. This is particularly important in multi-threaded and
multi-core systems where concurrency is prevalent.
4. Fault Isolation: IPC provides mechanisms for isolating and containing faults within
individual processes. By separating processes and enforcing boundaries between
them, IPC helps prevent errors and failures from spreading to other parts of the
system.
11
NotesNeo
Relationship with Process Synchronization
Process synchronization and IPC are closely related concepts that address different
aspects of concurrent programming.
● Process synchronization focuses on coordinating the execution of concurrent
processes or threads within a single system, ensuring that they access shared
resources in a mutually exclusive and orderly manner. IPC, on the other hand, deals
with communication and data exchange between processes, enabling them to
cooperate and coordinate their activities.
● While process synchronization mechanisms such as locks, semaphores, and
monitors ensure orderly access to shared resources, IPC mechanisms such as pipes,
shared memory, and message queues facilitate communication and data exchange
between processes. Together, process synchronization and IPC enable the
development of robust, scalable, and efficient concurrent systems and applications.
How it works:
● Processes send and receive messages to coordinate activities and exchange data.
● Communication Channels are established between processes, which can be either
direct or indirect.
● Synchronous Message Passing: The sender process waits until the receiver has
received the message. This ensures a tight coupling between processes but can
lead to delays if the receiver is slow or unavailable.
● Asynchronous Message Passing: The sender continues its execution without waiting
for the message to be received. This allows for concurrent execution and is more
flexible but requires mechanisms to handle message queues and potential
communication delays.
12
NotesNeo
2. Isolation and Encapsulation: Message passing promotes encapsulation and data
hiding by providing a mechanism for processes to communicate in a modular and
isolated manner. Processes communicate through well-defined interfaces (message
formats), which helps maintain modularity and encapsulation in the system.
3. Concurrency and Parallelism: Message passing supports concurrency and
parallelism by enabling processes to communicate and synchronize their actions in
a distributed or parallel computing environment. Processes can communicate and
exchange messages concurrently, allowing for efficient utilization of resources and
scalability.
13
NotesNeo
14
NotesNeo
Key Challenges:
1. Buffer Synchronization: Ensuring proper management of the shared buffer to
prevent issues such as buffer overflow or underflow.
2. Mutual Exclusion: Ensuring that only one process (producer or consumer) accesses
the buffer at a time to prevent data corruption.
Solution Approaches
We will use the Signal() and wait() operation in the above-mentioned semaphores to
arrive at a solution to the Producer-Consumer problem.
Signal() - The signal function increases the semaphore value by 1.
Wait() - The wait operation decreases the semaphore value by 1.
15
NotesNeo
Producer Process:
void Producer(){
while(true){
// producer produces an item/data
wait(Empty); // Waits for space in the buffer
wait(mutex); // Enters critical section
add(); // Adds item to the buffer
signal(mutex); // Exits critical section
signal(Full); // Indicates buffer is no longer empty
}
}
Consumer Process:
void Consumer() {
while(true){
// consumer consumes an item
wait(Full); // Waits for an item in the buffer
wait(mutex); // Enters critical section
consume(); // Consumes item from the buffer
signal(mutex);// Exits critical section
signal(Empty);// Indicates buffer is no longer full
}
}
16
NotesNeo
1. wait(Full) - Before the consumer process starts consuming any item from the buffer
it checks if the buffer is empty or has some item in it. So, the consumer process
creates one more empty space in the buffer and this is indicated by the full
variable. The value of the full variable decreases by one when the wait(Full) is
executed. If the Full variable is already zero i.e the buffer is empty then the
consumer process cannot consume any item from the buffer and it goes in the
busy-waiting state.
2. wait(mutex) - It does the same as explained in the producer process. It decreases
the mutex by 1 and restricts another process to enter the critical section until the
consumer process increases the value of mutex by 1.
3. consume() - This function consumes an item from the buffer. when code reaches the
consuming () function it will not allow any other process to access the critical
section which maintains the data consistency.
4. signal(mutex) - After consuming the item it increases the mutex value by 1 so that
other processes which are in a busy-waiting state can access the critical section
now.
5. signal(Empty) - when a consumer process consumes an item it increases the value
of the Empty variable indicating that the empty space in the buffer is increased by
This solution ensures mutual exclusion to prevent multiple processes from accessing the
buffer simultaneously, and it also ensures that producers wait if the buffer is full and
consumers wait if the buffer is empty, achieving synchronization between the two
processes.
17
NotesNeo
Key Challenges:
1. Read Access vs. Write Access:
● Readers can access the resource concurrently, but writers need exclusive
access to prevent data corruption.
● Readers should not be allowed to access the resource while a writer is
writing.
2. Data Consistency:
● Ensuring that readers see consistent data even if writers are actively writing
to the resource.
● Preventing issues such as data corruption or inconsistencies.:
Example:
Consider a scenario where multiple readers and writers want to access a shared file
simultaneously. We can analyze different cases to determine whether access should be
allowed or not:
18
NotesNeo
Explanation of Cases:
1. Case 1 (Writing-Writing): If two or more writers attempt to access the file
simultaneously, only one is allowed while others are blocked.
2. Case 2 (Reading-Writing): When a writer is writing, readers are blocked to maintain
data consistency.
3. Case 3 (Writing-Reading): Similarly, when a writer is writing, other readers are
blocked to prevent inconsistencies.
4. Case 4 (Reading-Reading): Multiple readers are allowed to access the file
simultaneously as long as no writer is writing.
Solution Approaches
19
NotesNeo
Solution/Implementation using Semaphores
The readers-writers problem involves managing access to a shared resource, such as a
file, by multiple processes concurrently. To solve this problem, binary semaphores can be
employed. Binary semaphores are synchronization primitives that allow only two possible
values: 0 and 1.
Binary Semaphore Operations:
1. wait(S): If the value of semaphore S is 0, the process executing this operation will
wait until it becomes 1. If the value is already 1, the operation decrements the
value of S by 1.
2. signal(S): This operation increments the value of semaphore S by 1.
Reader Process:
● Initialize a semaphore mutex and a variable readcount to manage access.
● Upon entering the critical section:
● Wait on the mutex semaphore to ensure mutual exclusion.
● Increment readcount to indicate a reader is accessing the resource.
● If readcount is 1 (i.e., the first reader), wait on the write semaphore to
prevent writers from accessing.
● Release the mutex semaphore.
● Perform reading operations.
● Upon exiting the critical section:
● Wait on the mutex semaphore.
● Decrement readcount.
● If readcount becomes 0 (i.e., no readers), signal the write semaphore to
allow writers to access.
● Release the mutex semaphore.
wait(mutex);
readcount++; // Increment readcount on entry
if (readcount == 1) {
wait(write); // Lock write if first reader
}
signal(mutex);
wait(mutex);
readcount--; // Decrement readcount on exit
if (readcount == 0) {
signal(write); // Unlock write if last reader
}
signal(mutex);
20
NotesNeo
Writer Process:
● Wait on the write semaphore to ensure mutual exclusion for writing operations.
● Perform writing operations on the shared resource.
● Signal the write semaphore to release access to the resource.
21
NotesNeo
● Each reader, upon entry, increments readcount.
● All readers can concurrently read as mutex allows access.
● When a writer arrives, it blocks all readers by setting write to 0.
● Upon completion of reading, readers decrement readcount.
● When readcount becomes 0, the writer is allowed to write.
22
NotesNeo
Key Challenges:
1. Deadlock Prevention:
23
NotesNeo
● Ensure that the philosophers cannot reach a state where each philosopher
holds one chopstick and waits indefinitely for the other.
2. Starvation Avoidance:
● Design a solution that prevents any philosopher from being indefinitely
prevented from accessing the shared resource (bowl of noodles).
Solution Approaches
1. Using Semaphores:
● Employ binary semaphores to represent the availability of each chopstick.
● Each chopstick is associated with a semaphore, and philosophers must acquire
both semaphores (chopsticks) to eat.
● Implement logic to handle the potential for deadlock, such as enforcing a
maximum number of philosophers allowed to pick up chopsticks simultaneously.
2. Using Monitors:
● Encapsulate the dining table and chopsticks within a monitor.
● Define monitor procedures for picking up and releasing chopsticks, ensuring
mutual exclusion.
● Implement a mechanism to detect and prevent deadlocks, such as allowing
philosophers to pick up both chopsticks only if both are available simultaneously.
// Philosopher process
void philosopher(int id) {
while (true) {
think(); // Philosopher is thinking
take_chopsticks(id); // Philosopher tries to pick up chopsticks
eat(); // Philosopher is eating
put_chopsticks(id); // Philosopher puts down chopsticks
}
}
24
NotesNeo
void take_chopsticks(int id) {
wait(chopstick[id]); // Wait for left chopstick
wait(chopstick[(id + 1) % 5]); // Wait for right chopstick
}
Explanation:
● Each philosopher is represented by a process, and there are five philosophers (0 to
4).
● The philosopher function represents the main behavior of a philosopher, where they
alternate between thinking, picking up chopsticks, eating, and putting down
chopsticks.
● think() represents the philosopher's thinking state.
● take_chopsticks(id) and put_chopsticks(id) represent the actions of picking up and
putting down chopsticks, respectively.
● In take_chopsticks(id), a philosopher tries to acquire both the left and right
chopsticks by waiting on the corresponding semaphores. The modulo operation (id
+ 1) % 5 ensures that the philosopher wraps around the table to pick up the right
chopstick for philosopher 4.
● In put_chopsticks(id), the philosopher releases both chopsticks by signaling the
corresponding semaphores.
● Each chopstick is represented by a semaphore initialized to 1, indicating
availability. When a philosopher picks up a chopstick, the semaphore value is
decremented (wait operation), and when they put down a chopstick, the
semaphore value is incremented (signal operation).
This implementation ensures that philosophers follow the rules of picking up and putting
down chopsticks in a coordinated manner, preventing deadlock and ensuring mutual
exclusion.
Section 2 : Deadlocks
2.1 Definition:
● A deadlock is a state where two or more processes are unable to proceed because
each is waiting for the other to release resources. Essentially, the processes are
stuck in a circular dependency, where each process holds a resource that another
process needs to continue execution.
25
NotesNeo
Scenario of Deadlocks:
● Imagine three processes, P1, P2, and P3, each holding a resource (R1, R2, R3) and
waiting for another resource held by a different process.
● For example, P1 may be waiting for R2 held by P2, P2 may be waiting for R3 held by
P3, and P3 may be waiting for R1 held by P1.
● This creates a cycle of dependencies where no process can proceed, causing the
system to become unresponsive.
26
NotesNeo
● However, not every case of starvation leads to deadlock.
● Deadlock specifically refers to the scenario where processes are stuck in a cyclic
dependency, while starvation refers to the situation where certain processes are
unable to proceed due to resource allocation policies.
Necessary Conditions:
1. Mutual Exclusion: Each resource can be assigned to only one process or thread at
a time.
2. Hold and Wait: A process holds at least one resource and is waiting to acquire
additional resources held by other processes.
3. No Preemption: Resources cannot be forcibly taken from a process; they must be
released voluntarily.
4. Circular Wait: There must be a circular chain of two or more processes, each
waiting for a resource held by the next process in the chain.
Sufficient Conditions:
● All the necessary conditions must hold simultaneously for a deadlock to occur.
27
NotesNeo
● Requires careful resource allocation and scheduling to ensure deadlock-free
execution.
4. Deadlock Detection and Recovery:
● Allows processes to potentially enter deadlock, but periodically checks the
system to detect if deadlock has occurred.
● If deadlock is detected, the system applies recovery methods to resolve the
deadlock.
● Recovery methods may include killing one or more processes involved in the
deadlock, preempting resources, rolling back processes, or restarting
affected processes.
● This approach involves overhead in terms of system monitoring and
recovery mechanisms but ensures that deadlocks are resolved once
detected.
28
NotesNeo
2. No Hold and Wait:
● Deadlock arises when processes hold resources while waiting for others,
creating a circular dependency. To prevent this, processes should request
and hold all necessary resources before execution starts.
● This approach is not practical in many cases because processes often
cannot determine all required resources beforehand. Additionally, it can
increase the risk of starvation if processes hold resources for long durations.
3. Preemption:
● Deadlock occurs because processes cannot be forcibly stopped once they
acquire resources. Preemption involves forcibly taking resources from
processes to break deadlocks.
● However, preempting resources can lead to inconsistent states and
performance inefficiencies. For example, preempting a printer resource from
a process midway through printing could lead to incomplete or inconsistent
output.
4. No Circular Wait:
● Deadlock arises when processes wait for resources held by other processes
in a circular chain. To prevent this, assign a priority to each resource and
ensure that processes can only request resources of equal or higher priority.
● By enforcing priority-based resource requests, processes cannot form
circular chains of dependencies, thereby preventing deadlock.
Among these methods, preventing circular wait is the most practical and commonly
implemented approach. It ensures that processes cannot enter into circular dependencies,
thereby eliminating the possibility of deadlock.
29
NotesNeo
It is also known as deadlock avoidance or deadlock detection algorithm in the
operating system.
Real-World Analogy:
● Imagine a scenario in a bank where the number of account holders represents
processes, and the total money in the bank represents available system resources.
● When an account holder applies for a loan, the bank subtracts the loan amount
from its total cash and ensures that the remaining cash is still sufficient to meet
future loan requests or withdrawals.
● Similarly, in an operating system, when a new process is created, it provides
information about its resource requirements to the OS.
● The OS, acting like a banker, evaluates these requests and ensures that allocating
resources to processes won't lead to resource starvation or deadlock.
Advantages:
1. Ensures deadlock avoidance by carefully allocating resources.
2. Helps in managing and controlling resource requests efficiently.
3. Allows sharing of resources among processes in a controlled manner.
4. Provides a systematic approach to resource allocation, reducing the risk of
deadlocks.
Disadvantages:
1. Requires processes to specify their maximum resource requirements in advance.
2. Assumes a fixed number of processes, limiting scalability.
3. May lead to underutilization of resources if processes overestimate their
requirements.
4. Requires careful implementation to avoid inefficiencies and race conditions.
Implementation:
In the Banker's Algorithm, several data structures are used to manage resource allocation
and ensure deadlock avoidance. These data structures include:
1. Available: A vector of length m (number of resource types) indicating the number
of available instances of each resource type.
2. Max: An n x m matrix defining the maximum demand of each process. Max[i][j] is
the maximum number of instances of resource type j that process i may request.
30
NotesNeo
3. Allocation: An n x m matrix defining the number of instances of each resource type
currently allocated to each process. Allocation[i][j] is the number of instances of
resource type j currently allocated to process i.
4. Need: An n x m matrix indicating the remaining resource need of each process.
Need[i][j] = Max[i][j] - Allocation[i][j].
Also, Available[i][j] >= Need[i][j] for safe sequence to occur where deadlock
doesn’t occur.
The Banker's Algorithm is the combination of the safety algorithm and the resource
request algorithm :
Safety Algorithm:
The safety algorithm checks if the system is in a safe state:
1. Initialize Work = Available and Finish[i] = false for all processes i.
2. Find an index i such that:
● Finish[i] == false
● Need[i] <= Work
● If no such i exists, go to step 4.
3. Set Work = Work + Allocation[i] and Finish[i] = true. Go to step 2.
4. If Finish[i] == true for all i, the system is in a safe state.
Example:
Consider a system with five processes {P1, P2, P3, P4, P5} and three resources {A, B, C}.
Resource type A has 10 instances, B has 5 instances and type C has 7 instances.
Total Available Resources: 3, 3, 2 initially.
A B C A B C A B C A B C
31
NotesNeo
P1 0 1 0 7 5 3 3 3 2 7 4 3
P2 2 0 0 3 2 2 5 3 2 1 2 2
P3 3 0 2 9 0 2 7 4 3 6 0 0
P4 2 1 1 2 2 2 7 4 5 0 1 1
P5 0 0 2 5 3 3 7 5 5 5 3 1
32
NotesNeo
● Need: (7, 4, 3)
● Available: (7, 4, 5)
● Since (7, 4, 3) <= (7, 4, 5), P1 can proceed.
● New Available after P1 finishes: (7, 4, 5) + (0, 1, 0) = (7, 5, 5)
● Step 7: For Process P3:
● Need: (6, 0, 0)
● Available: (7, 5, 5)
● Since (6, 0, 0) <= (7, 5, 5), P3 can proceed.
● New Available after P3 finishes: (7, 5, 5) + (3, 0, 2) = (10, 5, 7)
Safe Sequence:
Based on the above steps, the safe sequence is: P2 -> P4 -> P5 -> P1 -> P3.
Vertices:
1. Process (Circle): Each process in the system is represented by a circle.
2. Resource (Rectangle): Resources in the system, such as printers or memory units,
are depicted by rectangles.
Instances:
● Each resource rectangle may contain one or more dots inside, representing the
instances of that resource.
Edges:
1. Assignment Edge: An arrow from a resource to the process currently holding it.
2. Request Edge: An arrow from a process to a resource it wants.
33
NotesNeo
Example:
Consider a scenario with three processes (P1, P2, P3) and two types of resources (R1, R2),
each with one instance.
● The graph is deadlock free since no cycle is being formed in the graph.
Example:
● Consider a system with three processes (P1, P2, P3) and three resources (R1, R2,
R3), each having a single instance. The RAG shows the current allocation and
requests.
34
NotesNeo
● The system has deadlock because cycle is being formed in the graph.
RAG Analysis:
The RAG forms a cycle involving all processes and resources, indicating that the system
satisfies the four conditions of deadlock:
1. Mutual Exclusion: Each resource is assigned to exactly one process.
2. Hold and Wait: Processes holding resources are waiting for other resources.
3. No Preemption: Resources cannot be forcibly taken from processes.
4. Circular Wait: There exists a cycle in the graph.
Process R1 R2 R3
P1 0 0 1
P2 1 0 0
P3 0 1 0
Process R1 R2 R3
P1 1 0 0
P2 0 1 0
P3 0 0 1
35
NotesNeo
Deadlock Detection Algorithm
1. Initialization:
■ Work = Available (0, 0, 0)
■ Finish[i] = False for all i
2. Find a Process:
■ Find a process Pi such that both:
○ Finish[i] = False
○ Request[i] <= Work
■ If no such process exists, go to step 4.
3. Resource Allocation:
■ If such a process is found:
○ Work = Work + Allocation[i]
○ Finish[i] = True
○ Go to step 2.
4. Check for Deadlock:
■ If Finish[i] = False for any i, the system is in deadlock.
Deadlock Detection:
1. Periodic checks: The operating system periodically checks the system for deadlock
conditions.
36
NotesNeo
2. Resource allocation graph (RAG): The OS may use a resource allocation graph to
detect deadlocks. If a cycle is present in the graph, it indicates a potential
deadlock.
3. Matrix representations: In systems with multiple instances of resources, deadlock
detection may involve converting the resource allocation graph into allocation and
request matrices. The system checks for unsafe states where processes cannot
proceed without leading to deadlock.
Deadlock Recovery:
Once deadlock is detected, the OS can choose from several recovery techniques to resolve
the deadlock:
1. Preempt the resource: The OS can forcibly reclaim resources from one or more
processes and allocate them to others. This is done with the hope that the affected
processes can continue execution and release resources to resolve the deadlock.
2. Rollback to a safe state: The OS may rollback the system to a previously known
safe state. This involves reverting resource allocations to a point where deadlock
did not exist. Checkpoints are used to mark safe states in the system's execution.
3. Kill a process: The OS may terminate one or more processes to break the
deadlock. Typically, the process chosen for termination is the one that has done the
least amount of work, minimizing the impact on overall system functionality.
4. Kill all processes: As a last resort, the OS may choose to terminate all processes in
the system. This approach is highly disruptive and inefficient, as it requires all
processes to restart from the beginning.
July 2022
1. What is critical section problem ?
37
NotesNeo
Others
2. Is it possible to have a deadlock involving only one process? Explain your answer.
3. Explain semaphores.
4. Write a short note on Critical section.
5. What are buffering and spooling?
May 2023
1. (a) What is deadlock? Explain various methods for detecting, prevention and
recovery of deadlocks.
(b) Explain Banker’s algorithm briefly.
2. (a) What is Inter Process Communication (IPC) ? Explain Dining Philosopher IPC
problem in detail.
(b) What is semaphore? Explain counting and binary semaphore in detail.
July 2022
3. What is semaphores? Implement readers writers problem using semaphores.
4. What is deadlock? What are the conditions to prevent deadlock in a system?
July 2021
5. What is critical section problem? Explain IPC (Inter Process Communication) Dining
Philosophers problem with implementation using semaphore.
6. What is deadlock? What are the necessary conditions for a deadlock? Explain the
mechanism for a deadlock recovery.
Others
7. What are the algorithms for deadlock prevention?
38