SPOS Assignment No.
05
Q.1 What is Mutual Exclusion?
Definition:
Mutual exclusion is a fundamental principle in operating systems
and concurrent programming that ensures only one process or
thread can access a shared resource or critical section of code
at a time. This prevents conflicts and maintains data consistency
when multiple processes attempt to modify shared resources
simultaneously.
Key Features:
• Purpose: Prevents simultaneous access to shared
resources (e.g., variables, files, devices) to avoid data
corruption or inconsistent states.
• Implementation: Achieved using synchronization
mechanisms like semaphores, monitors, or locks.
• Requirements:
1. Mutual Exclusivity: Only one process can execute
the critical section at a time.
2. Progress: A process not in the critical section cannot
block others from entering.
3. Bounded Waiting: There must be a limit on the
waiting time for a process to enter the critical section.
4. No Busy Waiting (optional): Processes should not
consume CPU cycles while waiting (achieved by
blocking).
• Example: In a banking system, mutual exclusion ensures
that only one process can update an account balance at a
time to prevent errors during concurrent withdrawals or
deposits.
Importance:
Mutual exclusion is critical in multi-user or multi-threaded
environments to ensure data integrity and prevent race
conditions. Without it, concurrent modifications to shared
resources can lead to unpredictable results.
Q.2 Write a Note on Synchronization & Concurrency.
Synchronization:
Synchronization refers to the coordination of multiple processes
or threads to ensure orderly execution and consistent access to
shared resources. It prevents conflicts, such as race conditions,
by controlling the timing of process execution.
• Purpose: Ensures data consistency and prevents errors
when multiple processes access shared resources.
• Mechanisms:
o Semaphores: Variables used to control access to
shared resources.
o Monitors: High-level constructs that combine mutual
exclusion and condition variables.
o Locks: Simple mechanisms to restrict access to a
resource (e.g., mutex locks).
o Message Passing: Processes communicate and
synchronize via messages.
• Types:
o Mutual Exclusion: Ensures only one process
accesses a critical section.
o Condition Synchronization: Ensures a process
waits for a specific condition (e.g., resource
availability).
• Example: In a database system, synchronization ensures
that multiple transactions do not overwrite each other’s
updates.
Concurrency:
Concurrency refers to the ability of an operating system to
execute multiple processes or threads simultaneously,
leveraging multi-core CPUs or time-sharing. It improves system
efficiency by allowing processes to run in parallel or interleaved.
• Purpose: Enhances CPU utilization, reduces response
time, and supports multitasking.
• Challenges:
o Race Conditions: Occur when processes access
shared resources without proper synchronization.
o Deadlocks: When processes wait indefinitely for
resources held by each other.
o Starvation: When a process is perpetually denied
resources.
• Types:
o True Concurrency: Processes run simultaneously on
multiple CPUs.
o Apparent Concurrency: Processes share a single
CPU through time-slicing (e.g., Round Robin
scheduling).
• Example: A web browser runs multiple tabs concurrently,
with each tab performing tasks like rendering pages or
downloading files.
Relation:
Synchronization is essential in concurrent systems to manage
access to shared resources, ensuring that concurrency does not
lead to errors like race conditions or data inconsistency. For
example, in a multi-threaded application, synchronization
mechanisms like mutexes ensure that threads do not corrupt
shared data structures.
Q.3 Explain Race Condition with Example.
Definition:
A race condition occurs when the outcome of a program
depends on the unpredictable order or timing of process or
thread execution, leading to inconsistent or erroneous results. It
typically arises when multiple processes access and modify a
shared resource without proper synchronization.
Key Features:
• Cause: Lack of mutual exclusion when accessing shared
resources.
• Consequences: Data corruption, inconsistent states, or
program crashes.
• Prevention: Use synchronization mechanisms like locks,
semaphores, or monitors to enforce mutual exclusion.
Example:
Consider a banking system with a shared account balance of
$1000. Two processes, P1 (withdrawal of $600) and P2
(withdrawal of $500), execute concurrently without
synchronization.
• Scenario:
1. P1 reads the balance ($1000) and checks if $600 can
be withdrawn (sufficient funds).
2. Before P1 updates the balance, P2 reads the same
balance ($1000) and checks if $500 can be withdrawn
(sufficient funds).
3. P1 updates the balance to $400 ($1000 - $600).
4. P2 updates the balance to $500 ($1000 - $500),
overwriting P1’s update.
• Result: The final balance is $500, but both withdrawals
($600 + $500 = $1100) were allowed, leading to an
incorrect balance. This is a race condition because the
outcome depends on the interleaving of P1 and P2’s
operations.
• Solution: Use a mutex lock to ensure that only one process
can access and modify the balance at a time, preventing
concurrent updates.
Diagram:
Process P1 Process P2
| Read balance ($1000) | Read balance ($1000)
| Check $600 (OK) | Check $500 (OK)
| Write balance ($400) | Write balance ($500)
v v
Incorrect Final Balance: $500
Prevention:
Using a mutex lock, P1 would lock the balance, complete its
withdrawal, and unlock it before P2 can access it, ensuring the
correct final balance ($1000 - $600 - $500 = -$100, or reject the
second withdrawal if insufficient funds).
Q.4 Explain Critical Sections & Problems.
Definition:
A critical section is a part of a program where a process
accesses or modifies a shared resource (e.g., variable, file, or
database). Only one process or thread should execute its critical
section at a time to avoid conflicts.
Characteristics:
• Shared Resource Access: Critical sections involve
operations on shared resources that must be protected.
• Mutual Exclusion: Only one process can execute its
critical section at a time.
• Example: In a multi-threaded program, a critical section
might update a shared counter variable.
Requirements for Critical Section Management:
1. Mutual Exclusion: At most one process can execute the
critical section.
2. Progress: A process outside the critical section cannot
block others from entering.
3. Bounded Waiting: There must be a limit on the time a
process waits to enter the critical section.
4. No Busy Waiting (optional): Waiting processes should be
blocked, not consume CPU cycles.
Problems Associated with Critical Sections:
1. Race Conditions:
o Occurs when multiple processes execute their critical
sections concurrently without synchronization, leading
to inconsistent results.
o Example: Two threads incrementing a shared counter
without locks can miss updates, resulting in an
incorrect count.
2. Deadlocks:
o When multiple processes hold resources and wait for
each other’s resources, none can proceed.
o Example: Process P1 holds Resource A and waits for
Resource B, while Process P2 holds Resource B and
waits for Resource A.
3. Starvation:
o A process is perpetually denied access to the critical
section due to higher-priority processes.
o Example: In priority-based scheduling, low-priority
processes may never enter the critical section.
4. Priority Inversion:
o A higher-priority process is delayed by a lower-priority
process holding a shared resource.
o Example: A low-priority process in a critical section
blocks a high-priority process, causing delays.
5. Overhead of Synchronization:
o Synchronization mechanisms (e.g., locks,
semaphores) introduce performance overhead due to
context switching or waiting.
o Example: Excessive locking can reduce concurrency
and slow down the system.
Solutions:
• Use synchronization tools like semaphores, monitors, or
mutex locks to enforce mutual exclusion.
• Implement algorithms like Peterson’s solution or Dekker’s
algorithm for two-process synchronization.
• Use priority inheritance to mitigate priority inversion.
• Employ aging to prevent starvation by increasing the
priority of waiting processes.
Example:
In a database application, the critical section might involve
updating a record. Without mutual exclusion, concurrent updates
by two transactions could overwrite each other, leading to data
corruption. A lock ensures only one transaction updates the
record at a time.
Q.5 Write a Note on Semaphores.
Definition:
A semaphore is a synchronization primitive used to control
access to shared resources in a concurrent system. It is a
variable that maintains a count and supports two atomic
operations: wait() (decrement) and signal() (increment).
Types of Semaphores:
1. Binary Semaphore:
o Takes only two values (0 or 1), acting like a mutex
lock.
o Used for mutual exclusion (e.g., one process in a
critical section).
o Example: Locking a printer resource so only one
process can print at a time.
2. Counting Semaphore:
o Takes non-negative integer values, representing the
number of available resources.
o Used for resource management (e.g., controlling
access to a pool of resources).
o Example: Managing access to 5 database
connections.
Operations:
• wait() (P): Decrements the semaphore value. If the value is
0, the process blocks until the semaphore is available.
• signal() (V): Increments the semaphore value, waking up a
blocked process if any.
• Both operations are atomic to prevent race conditions.
Features:
• Atomicity: Ensures operations are indivisible, preventing
concurrent modifications.
• Blocking: Processes waiting on a semaphore are blocked,
not busy-waiting, saving CPU cycles.
• Flexibility: Supports both mutual exclusion and resource
management.
Advantages:
• Simple and effective for synchronization.
• Prevents race conditions and ensures mutual exclusion.
• Suitable for both single and multiple resource scenarios.
Disadvantages:
• Improper use can lead to deadlocks or starvation.
• Requires careful management to avoid errors like forgetting
to signal.
• Limited expressiveness compared to monitors.
Example:
In a producer-consumer problem, a counting semaphore tracks
the number of items in a buffer. The producer calls signal() to
increment the semaphore after adding an item, and the
consumer calls wait() to decrement it before consuming an item.
Pseudocode for Binary Semaphore:
semaphore mutex = 1; // Binary semaphore initialized to 1
process P1() {
wait(mutex); // Enter critical section
// Critical section code
signal(mutex); // Exit critical section
}
Q.6 Explain Producer-Consumer Problem.
Definition:
The producer-consumer problem is a classic synchronization
problem where two types of processes—producers and
consumers—share a fixed-size buffer. Producers generate data
and place it in the buffer, while consumers remove and process
data from the buffer. The challenge is to ensure synchronization
and prevent issues like buffer overflow or underflow.
Key Components:
• Producer: Generates data and adds it to the buffer.
• Consumer: Removes and processes data from the buffer.
• Buffer: A fixed-size data structure (e.g., array or queue) to
store items.
• Synchronization Requirements:
o Mutual Exclusion: Only one process (producer or
consumer) can access the buffer at a time.
o Condition Synchronization:
▪ Producers must wait if the buffer is full.
▪ Consumers must wait if the buffer is empty.
Problem Scenario:
• If a producer adds data to a full buffer, it causes buffer
overflow (data loss).
• If a consumer removes data from an empty buffer, it causes
buffer underflow (invalid operation).
• Without mutual exclusion, concurrent access can lead to
race conditions (e.g., overwriting or reading inconsistent
data).
Solution Using Semaphores:
Semaphores are used to enforce mutual exclusion and condition
synchronization:
• mutex: A binary semaphore (initialized to 1) ensures
mutual exclusion for buffer access.
• full: A counting semaphore (initialized to 0) tracks the
number of items in the buffer.
• empty: A counting semaphore (initialized to buffer size,
e.g., N) tracks the number of empty slots.
Pseudocode:
semaphore mutex = 1; // For mutual exclusion
semaphore full = 0; // Number of items in buffer
semaphore empty = N; // Number of empty slots (N = buffer size)
Producer() {
while (true) {
produce_item();
wait(empty); // Wait if buffer is full
wait(mutex); // Lock buffer
add_item_to_buffer();
signal(mutex); // Unlock buffer
signal(full); // Increment full count
}
}
Consumer() {
while (true) {
wait(full); // Wait if buffer is empty
wait(mutex); // Lock buffer
remove_item_from_buffer();
signal(mutex); // Unlock buffer
signal(empty); // Increment empty count
consume_item();
}
}
Example:
• Buffer size = 5. Initially, empty = 5, full = 0, mutex = 1.
• Producer adds an item: wait(empty) (empty = 4),
wait(mutex) (mutex = 0), adds item, signal(mutex) (mutex =
1), signal(full) (full = 1).
• Consumer removes an item: wait(full) (full = 0), wait(mutex)
(mutex = 0), removes item, signal(mutex) (mutex = 1),
signal(empty) (empty = 5).
• This ensures no overflow, underflow, or race conditions.
Diagram:
Producer --> [ Buffer (size N) ] --> Consumer
| wait(empty), wait(mutex) | wait(full), wait(mutex)
| add item | remove item
| signal(mutex), signal(full) | signal(mutex), signal(empty)
Significance:
The producer-consumer problem models real-world scenarios
like task queues in operating systems, message passing in
networks, or data streaming in multimedia applications.
Q.7 Write a Note on Deadlock.
Definition:
A deadlock is a situation in a concurrent system where two or
more processes are unable to proceed because each is waiting
for a resource held by another, creating a circular wait. As a
result, all involved processes are blocked indefinitely.
Conditions for Deadlock:
For a deadlock to occur, the following four conditions must hold
simultaneously:
1. Mutual Exclusion: At least one resource is held in a non-
shareable mode (only one process can use it at a time).
2. Hold and Wait: A process holding at least one resource is
waiting to acquire additional resources held by other
processes.
3. No Preemption: Resources cannot be forcibly taken from
a process; the process must release them voluntarily.
4. Circular Wait: A set of processes form a circular chain,
where each process waits for a resource held by the next
process in the chain.
Example:
• Process P1 holds Resource R1 and waits for Resource R2.
• Process P2 holds Resource R2 and waits for Resource R1.
• Result: Neither P1 nor P2 can proceed, causing a
deadlock.
Diagram:
P1 --> R1 (held) --> R2 (waiting)
^ |
| v
P2 <-- R2 (held) <-- R1 (waiting)
Deadlock Handling Strategies:
1. Deadlock Prevention: Eliminate one of the four conditions:
o Mutual Exclusion: Use shareable resources (not
always feasible).
o Hold and Wait: Require processes to request all
resources at once.
o No Preemption: Allow resource preemption (e.g.,
forcibly release resources).
o Circular Wait: Assign a unique order to resources and
require processes to request them in that order.
2. Deadlock Avoidance: Use algorithms like the Banker’s
Algorithm to ensure safe resource allocation, preventing
deadlock.
3. Deadlock Detection and Recovery: Periodically detect
deadlocks and recover by:
o Terminating one or more processes.
o Preempting resources and rolling back processes.
4. Deadlock Ignorance: Ignore deadlocks, assuming they
are rare (common in general-purpose OS like Windows).
Advantages of Handling Deadlocks:
• Ensures system reliability and resource availability.
• Prevents indefinite blocking of processes.
Disadvantages:
• Prevention and avoidance add complexity and overhead.
• Detection and recovery may involve costly operations like
process termination.
Example in Real Life:
In a database system, Transaction T1 locks Table A and waits
for Table B, while Transaction T2 locks Table B and waits for
Table A. Without intervention, both transactions are deadlocked.
The database may use deadlock detection to terminate one
transaction and release its locks.
Significance:
Deadlocks are critical in operating systems, databases, and
distributed systems, as they can halt system progress. Proper
resource management and synchronization are essential to
mitigate deadlocks.