0% found this document useful (0 votes)
54 views137 pages

Unit-III: Threads, Process Synchronization & Deadlocks

Uploaded by

dinesh reddy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
54 views137 pages

Unit-III: Threads, Process Synchronization & Deadlocks

Uploaded by

dinesh reddy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 137

Unit-III:

Threads, Process Synchronization


& Deadlocks

Textbook Reference:
Operating System Concepts – 9th Edition
Silberschatz, Galvin and Gagne ©2013
Process
 The unit or resource allocation and a unit of protection.
 A virtual address space that holds the process image.
 Protected access to:
 processors
 other processes
 files
 I/O resources

Dept. of Computer Science and Engineering


Threads
 A thread is a basic unit of CPU utilization, consisting of a program counter, a stack,
and a set of registers, ( and a thread ID. ) 
 Traditional ( heavyweight ) processes have a single thread of control –
 There is one program counter, and one sequence of instructions that can be
carried out at any given time.
 Single sequence stream within a process
 A thread is a path of execution within a process. A process can contain multiple
threads.
 Process are used to group the resources together and threads are the entities
scheduled for execution on the CPU
  A thread of execution is the smallest sequence of programmed instructions that can
be managed independently by a scheduler
 The threads of a process share its executable code and the values of its dynamically
allocated variables and non-thread-local global variables at any given time.
Dept. of Computer Science and Engineering
Process vs Threads
Resource Ownership Scheduling/Execution
 Process includes a virtual address  Follows an execution path that may
space to hold the process image be interleaved with other processes
 the OS performs a protection  a process has an execution state
function to prevent unwanted (Running, Ready, etc.) and a
interference between processes dispatching priority and is
with respect to resources scheduled and dispatched by the
OS

• The unit of dispatching is referred to as a thread or lightweight process


• The unit of resource ownership is referred to as a process or task
• Multithreading - The ability of an OS to support multiple, concurrent paths of
execution within a single process
Dept. of Computer Science and Engineering
Threads
 Most modern applications are multithreaded
 Threads run within application
 Multiple tasks with the application can be implemented by separate threads
 Update display
 Fetch data
 Spell checking
 Answer a network request
 Process creation is heavy-weight while thread creation is light-weight
 Can simplify code, increase efficiency
 Kernels are generally multithreaded

Dept. of Computer Science and Engineering


One or More Threads in a Process

Each thread has:


 An execution state (Running, Ready, etc.)
 Saved thread context when not running
 An execution stack
 Some per-thread static storage for local variables.
 Access to the memory resources of its process (all threads of a process
share this)

Dept. of Computer Science and Engineering


Thread Process Model
Single-Threaded Multithreaded Process Model
Process Model
Thread Thread Thread
Control Control Control
Process Process Block Block Block
Control User Control
Block Stack Block
User User User
Stack Stack Stack
User Kernel User
Address Stack Address Kernel Kernel Kernel
Space Space Stack Stack Stack

Dept. of Computer Science and Engineering


Multithreaded Server Architecture

Dept. of Computer Science and Engineering


Benefits of Threads

 Responsiveness – may allow continued execution if part of process is


blocked, especially important for user interfaces
 Resource Sharing – threads share resources of process, easier than shared
memory or message passing
 Economy – cheaper than process creation, thread switching lower overhead
than context switching
 Scalability – process can take advantage of multiprocessor architectures

Dept. of Computer Science and Engineering


Benefits of Threads
 Takes less time to create a new thread than a process
 Less time to terminate a thread than a process
 Switching between two threads takes less time than switching between
processes.
 Threads enhance efficiency in communication between programs.
 In an OS that supports threads, scheduling and dispatching is done on a thread
basis
 Most of the state information dealing with execution is maintained in thread-
level data structures
 Suspending a process involves suspending all threads of the process.
 Termination of a process terminates all threads within the process.

Dept. of Computer Science and Engineering


Multicore Programming
 Multicore or multiprocessor systems putting pressure on
programmers, challenges include:
 Dividing activities
 Balance
 Data splitting
 Data dependency
 Testing and debugging
 Parallelism implies a system can perform more than one task
simultaneously
 Concurrency supports more than one task making progress
 Single processor / core, scheduler providing concurrency

Dept. of Computer Science and Engineering


Multicore Programming (Cont.)
 Types of parallelism
 Data parallelism – distributes subsets of the same data across
multiple cores, same operation on each
 Task parallelism – distributing threads across cores, each thread
performing unique operation
 As # of threads grows, so does architectural support for threading
 CPUs have cores as well as hardware threads
 Consider Oracle SPARC T4 with 8 cores, and 8 hardware threads
per core

Dept. of Computer Science and Engineering


Concurrency vs. Parallelism
 Concurrent execution on single-core system:

 Parallelism on a multi-core system:

Dept. of Computer Science and Engineering


Single and Multithreaded Processes

Dept. of Computer Science and Engineering


Amdahl’s Law

 Identifies performance gains from adding additional cores to an


application that has both serial and parallel components
 S is serial portion
 N processing cores

 That is, if application is 75% parallel / 25% serial, moving from 1 to 2


cores results in speedup of 1.6 times
 As N approaches infinity, speedup approaches 1 / S

Serial portion of an application has disproportionate effect on


performance gained by adding additional cores

 But does the law take into account contemporary multicore systems?

Dept. of Computer Science and Engineering


Thread Execution States
 The key states for a thread are:  Thread operations associated with
 Running a change in thread state are:

 Ready  Spawn

 Blocked  Block
 Unblock
 Finish

Dept. of Computer Science and Engineering


Remote Procedure Call Using Thread
RPC RPC
Request Request

(a) RPC Request Using Single Thread

Process 1

Server Server

RPC Server (b) RPC Using One Thread


Request per Server (on a uniprocessor)

Thread A (Process 1)

Thread B (Process 1)
RPC
Request
Server

Blocked, waiting for response to RPC

Blocked, waiting for processor, which is in use by Thread B


Running

Dept. of Computer Science and Engineering


Multithreading Example on a Uniprocessor

Time
I/O Request Time quantum
request Complete Expires

Thread A (Process 1)

Thread B (Process 1)

Time quantum
Expires

Process created

Blocked Ready Running

Dept. of Computer Science and Engineering


Thread Synchronization
 It is necessary to synchronize the activities of the various threads
 All threads of a process share the same address space and other
resources
 Any alteration of a resource by one thread affects the other threads in
the same process

Dept. of Computer Science and Engineering


Types of Threads
 User Level Thread (ULT):
 All threads are management is done by the application.
 The kernel is not aware of the existence of threads.

 Kernel Level Thread (KLT):


 Thread management is done by the kernel
 No thread management is done by the application
 Windows is an example of this approach.

Dept. of Computer Science and Engineering


Types of Threads

User
Threads User Space
Library Space
Kernel
Space
Kernel
Space

P
(a) Pure User Level Threads (b) Pure Kernel Level Threads

Dept. of Computer Science and Engineering


User Threads and Kernel Threads

 User threads - management done by user-level threads library


 Three primary thread libraries:
 POSIX Pthreads
 Windows threads
 Java threads
 Kernel threads - Supported by the Kernel
 Examples – virtually all general purpose operating systems, including:
 Windows
 Solaris
 Linux
 Tru64 UNIX
 Mac OS X

Dept. of Computer Science and Engineering


Relationships Between User-Level Thread States and Process States

(a) (b)

(c) (d)

Colored state is the current state

Dept. of Computer Science and Engineering


Advantages of ULTs
 ULTs can run on any OS
 Scheduling can be application specific
 Thread switching doesnot require kernel mode privileges.

Disadvantages of ULTs
 In a typical OS many system calls are blocking
 As a result, when a ULT executes a system call, not only is that thread
blocked, but all of the threads within the process are blocked
 In a pure ULT strategy, a multithreaded application cannot take advantage
of multiprocessing

Dept. of Computer Science and Engineering


Overcoming the disadvantages of ULT

Jacketing:
• Converts a blocking system call into a non-blocking system call

Writing an application as multiple processes rather than multiple


threads

Dept. of Computer Science and Engineering


Advantages of KLTs
 The kernel can simultaneously schedule multiple threads from the same process on
multiple processors
 If one thread in a process is blocked, the kernel can schedule another thread of the
same process
 Kernel routines can be multithreaded

Disadvantages of KLTs:
 The transfer of control from one thread to another within the same process requires a
mode switch to the kernel.

Dept. of Computer Science and Engineering


Multithreading Models

 Many-to-One

 One-to-One

 Many-to-Many

Dept. of Computer Science and Engineering


Many-to-One

 Many user-level threads mapped to single


kernel thread
 One thread blocking causes all to block
 Multiple threads may not run in parallel on
muticore system because only one may be in
kernel at a time
 Few systems currently use this model
 Examples:
 Solaris Green Threads
 GNU Portable Threads

Dept. of Computer Science and Engineering


One-to-One
 Each user-level thread maps to kernel thread
 Creating a user-level thread creates a kernel thread
 More concurrency than many-to-one
 Number of threads per process sometimes restricted due
to overhead
 Examples
 Windows
 Linux
 Solaris 9 and later

Dept. of Computer Science and Engineering


Many-to-Many Model
 Allows many user level threads to be
mapped to many kernel threads
 Allows the operating system to create a
sufficient number of kernel threads
 Solaris prior to version 9
 Windows with the ThreadFiber package

Dept. of Computer Science and Engineering


Two-level Model
 Similar to M:M, except that it allows a user thread to be bound
to kernel thread
 Examples
 IRIX
 HP-UX
 Tru64 UNIX
 Solaris 8 and earlier

Dept. of Computer Science and Engineering


Process Synchronization

Textbook Reference:
Operating System Concepts – 9th Edition
Silberschatz, Galvin and Gagne ©2013
Objectives
 To present the concept of process synchronization.
 To introduce the critical-section problem, whose solutions can be used to ensure
the consistency of shared data
 To present both software and hardware solutions of the critical-section problem
 To examine several classical process-synchronization problems
 To explore several tools that are used to solve process synchronization problems

Dept. of Computer Science and Engineering


Background
 Processes can execute concurrently
 May be interrupted at any time, partially completing execution
 Concurrent access to shared data may result in data inconsistency
 Maintaining data consistency requires mechanisms to ensure the orderly
execution of cooperating processes
 Illustration of the problem:
Suppose that we wanted to provide a solution to the consumer-producer problem
that fills all the buffers. We can do so by having an integer counter that keeps
track of the number of full buffers. Initially, counter is set to 0. It is incremented
by the producer after it produces a new buffer and is decremented by the
consumer after it consumes a buffer.

Dept. of Computer Science and Engineering


Producer

while (true) {
/* produce an item in next produced */

while (counter == BUFFER_SIZE) ;


/* do nothing */
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}

Dept. of Computer Science and Engineering


Consumer

while (true) {
while (counter == 0)
; /* do nothing */
next_consumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
/* consume the item in next consumed */
}

Dept. of Computer Science and Engineering


Race Condition
 counter++ could be implemented as
register1 = counter
register1 = register1 + 1
counter = register1
 counter-- could be implemented as
register2 = counter
register2 = register2 - 1
counter = register2

 Consider this execution interleaving with “count = 5” initially:


S0: producer execute register1 = counter {register1 = 5}
S1: producer execute register1 = register1 + 1 {register1 = 6}
S2: consumer execute register2 = counter {register2 = 5}
S3: consumer execute register2 = register2 – 1 {register2 = 4}
S4: producer execute counter = register1 {counter = 6 }
S5: consumer execute counter = register2 {counter = 4}

Dept. of Computer Science and Engineering


Critical Section Problem
 Consider system of n processes {p0, p1, … pn-1}
 Each process has critical section segment of code
 Process may be changing common variables, updating table, writing file,
etc
 When one process in critical section, no other may be in its critical
section
 Critical section problem is to design protocol to solve this
 Each process must ask permission to enter critical section in entry
section, may follow critical section with exit section, then
remainder section

Dept. of Computer Science and Engineering


Critical Section

 General structure of process Pi

Dept. of Computer Science and Engineering


Algorithm for Process Pi

do {

while (turn == j);

critical section
turn = j;

remainder section
} while (true);

Dept. of Computer Science and Engineering


Solution to Critical-Section Problem
1. Mutual Exclusion - If process Pi is executing in its critical section, then no
other processes can be executing in their critical sections
2. Progress - If no process is executing in its critical section and there exist
some processes that wish to enter their critical section, then the selection of
the processes that will enter the critical section next cannot be postponed
indefinitely
3. Bounded Waiting - A bound must exist on the number of times that other
processes are allowed to enter their critical sections after a process has
made a request to enter its critical section and before that request is granted
 Assume that each process executes at a nonzero speed
 No assumption concerning relative speed of the n processes

Dept. of Computer Science and Engineering


Critical-Section Handling in OS
Two approaches depending on if kernel is preemptive or non-
preemptive
 Preemptive – allows preemption of process when running in kernel mode
 Non-preemptive – runs until exits kernel mode, blocks, or voluntarily
yields CPU
 Essentially free of race conditions in kernel mode

Dept. of Computer Science and Engineering


Peterson’s Solution
 Good algorithmic description of solving the problem
 Two process solution
 Assume that the load and store machine-language instructions
are atomic; that is, cannot be interrupted
 The two processes share two variables:
 int turn;
 Boolean flag[2]

 The variable turn indicates whose turn it is to enter the critical section
 The flag array is used to indicate if a process is ready to enter the
critical section. flag[i] = true implies that process Pi is ready!

Dept. of Computer Science and Engineering


Algorithm for Process Pi and Pj

do { do {
flag[i] = true; flag[j] = true;
turn = j; turn = i;
while (flag[j] && turn = = while (flag[i] && turn = =
j); i);
critical section critical section
flag[i] = false; flag[j] = false;
remainder section remainder section
} while (true); } while (true);

The structure of process Pi in The structure of process Pj in


Peterson’s solution. Peterson’s solution.

Dept. of Computer Science and Engineering


Peterson’s Solution (Cont.)
 Provable that the three CS requirement are met:
1. Mutual exclusion is preserved
Pi enters CS only if:
either flag[j] = false or turn = i
2. Progress requirement is satisfied
3. Bounded-waiting requirement is met

Dept. of Computer Science and Engineering


Synchronization Hardware
 Many systems provide hardware support for implementing the critical
section code.
 All solutions below based on idea of locking
 Protecting critical regions via locks
 Uniprocessors – could disable interrupts
 Currently running code would execute without preemption
 Generally too inefficient on multiprocessor systems
 Operating systems using this not broadly scalable

 Modern machines provide special atomic hardware instructions


 Atomic = non-interruptible
 Either test memory word and set value
 Or swap contents of two memory words

Dept. of Computer Science and Engineering


Solution to Critical-section Problem Using Locks

do {
acquire lock
critical section
release lock
remainder section
} while (TRUE);

Dept. of Computer Science and Engineering


test_and_set Instruction

Definition:
boolean test_and_set (boolean *target)
{
boolean rv = *target;
*target = TRUE;
return rv:
}
1. Executed atomically
2. Returns the original value of passed parameter
3. Set the new value of passed parameter to “TRUE”.

Dept. of Computer Science and Engineering


Solution using test_and_set()
 Shared Boolean variable lock, initialized to FALSE
 Solution:
do {
while (test_and_set(&lock))
; /* do nothing */
/* critical section */
lock = false;
/* remainder section */
} while (true);

Dept. of Computer Science and Engineering


compare_and_swap Instruction
Definition:
int compare_and_swap(int *value, int expected, int new_value) {
int temp = *value;
if (*value == expected)
*value = new_value;
return temp;
}

1. Executed atomically
2. Returns the original value of passed parameter “value”
3. Set the variable “value” the value of the passed parameter “new_value” but
only if “value” ==“expected”. That is, the swap takes place only under this
condition.

Dept. of Computer Science and Engineering


Solution using compare_and_swap
 Shared integer “lock” initialized to 0;
 Solution:
do {
while (compare_and_swap(&lock, 0, 1) != 0)
; /* do nothing */
/* critical section */
lock = 0;
/* remainder section */
} while (true);

Dept. of Computer Science and Engineering


Bounded-waiting Mutual Exclusion with test_and_set

do {
waiting[i] = true;
key = true;
while (waiting[i] && key)
key = test_and_set(&lock);
waiting[i] = false;
/* critical section */
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
else
waiting[j] = false;
/* remainder section */
} while (true);

Dept. of Computer Science and Engineering


Mutex Locks
 Previous solutions are complicated and generally inaccessible to
application programmers
 OS designers build software tools to solve critical section problem
 Simplest is mutex lock
 Protect a critical section by first acquire() a lock then
release() the lock
 Boolean variable indicating if lock is available or not
 Calls to acquire() and release() must be atomic
 Usually implemented via hardware atomic instructions
 But this solution requires busy waiting
 This lock therefore called a spinlock

Dept. of Computer Science and Engineering


acquire() and release()
 acquire() {
while (!available)
; /* busy wait */
available = false;;
}
 release() {
available = true;
}
 do {
acquire lock
critical section
release lock
remainder section
} while (true);

Dept. of Computer Science and Engineering


Semaphore

Textbook Reference:
Operating System Concepts – 9th Edition
Silberschatz, Galvin and Gagne ©2013
Semaphore
 Synchronization tool that provides more sophisticated ways (than Mutex locks) for process to
synchronize their activities.
 Semaphore S – integer variable
 Can only be accessed via two indivisible (atomic) operations
 wait() and signal()
 Originally called P() and V()
 Definition of the wait() operation
wait(S) {
while (S <= 0)
; // busy wait
S--;
}
 Definition of the signal() operation
signal(S) {
S++;
}

Dept. of Computer Science and Engineering


Semaphore Usage

 Counting semaphore – integer value can range over an unrestricted domain


 Binary semaphore – integer value can range only between 0 and 1
 Same as a mutex lock
 Can solve various synchronization problems
 Consider P1 and P2 that require S1 to happen before S2
Create a semaphore “synch” initialized to 0
P1:
S1;
signal(synch);
P2:
wait(synch);
S2;
 Can implement a counting semaphore S as a binary semaphore

Dept. of Computer Science and Engineering


Semaphore Implementation
 Must guarantee that no two processes can execute the wait() and
signal() on the same semaphore at the same time
 Thus, the implementation becomes the critical section problem where
the wait and signal code are placed in the critical section
 Could now have busy waiting in critical section implementation
 But implementation code is short
 Little busy waiting if critical section rarely occupied

 Note that applications may spend lots of time in critical sections and
therefore this is not a good solution

Dept. of Computer Science and Engineering


Semaphore Implementation with no Busy waiting

 With each semaphore there is an associated waiting queue


 Each entry in a waiting queue has two data items:
 value (of type integer)
 pointer to next record in the list
 Two operations:
 block – place the process invoking the operation on the appropriate waiting queue
 wakeup – remove one of processes in the waiting queue and place it in the ready queue
 typedef struct{
int value;
struct process *list;
} semaphore;

Dept. of Computer Science and Engineering


Implementation with no Busy waiting (Cont.)

wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
block();
}
}

signal(semaphore *S) {
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}

Dept. of Computer Science and Engineering


Deadlock and Starvation
 Deadlock – two or more processes are waiting indefinitely for an event that can
be caused by only one of the waiting processes
 Let S and Q be two semaphores initialized to 1
P0 P1
wait(S); wait(Q);
wait(Q); wait(S);
... ...
signal(S); signal(Q);
signal(Q); signal(S);

 Starvation – indefinite blocking


 A process may never be removed from the semaphore queue in which it is suspended
 Priority Inversion – Scheduling problem when lower-priority process holds a
lock needed by higher-priority process
 Solved via priority-inheritance protocol

Dept. of Computer Science and Engineering


Classical Problems of Synchronization
 Classical problems used to test newly-proposed synchronization schemes
 Bounded-Buffer Problem
 Readers and Writers Problem
 Dining-Philosophers Problem

Dept. of Computer Science and Engineering


Bounded-Buffer Problem

 n buffers, each can hold one item


 Semaphore mutex initialized to the value 1
 Semaphore full initialized to the value 0
 Semaphore empty initialized to the value n

Dept. of Computer Science and Engineering


Bounded Buffer Problem (Cont.)

 The structure of the producer process

do {
...
/* produce an item in next_produced */
...
wait(empty);
wait(mutex);
...
/* add next produced to the buffer */
...
signal(mutex);
signal(full);
} while (true);

Dept. of Computer Science and Engineering


Bounded Buffer Problem (Cont.)
 The structure of the consumer process

Do {
wait(full);
wait(mutex);
...
/* remove an item from buffer to next_consumed */
...
signal(mutex);
signal(empty);
...
/* consume the item in next consumed */
...
} while (true);

Dept. of Computer Science and Engineering


Readers-Writers Problem
 A data set is shared among a number of concurrent processes
 Readers – only read the data set; they do not perform any updates
 Writers – can both read and write
 Problem – allow multiple readers to read at the same time
 Only one single writer can access the shared data at the same time
 Several variations of how readers and writers are considered – all involve
some form of priorities
 Shared Data
 Data set
 Semaphore rw_mutex initialized to 1
 Semaphore mutex initialized to 1
 Integer read_count initialized to 0

Dept. of Computer Science and Engineering


Readers-Writers Problem (Cont.)

 The structure of a writer process

do {
wait(rw_mutex);
...
/* writing is performed */
...
signal(rw_mutex);
} while (true);

Dept. of Computer Science and Engineering


Readers-Writers Problem (Cont.)
 The structure of a reader process
do {
wait(mutex);
read_count++;
if (read_count == 1)
wait(rw_mutex);
signal(mutex);
...
/* reading is performed */
...
wait(mutex);
read count--;
if (read_count == 0)
signal(rw_mutex);
signal(mutex);
} while (true);

Dept. of Computer Science and Engineering


Readers-Writers Problem Variations
 First variation – no reader kept waiting unless writer has
permission to use shared object
 Second variation – once writer is ready, it performs the write
ASAP
 Both may have starvation leading to even more variations
 Problem is solved on some systems by kernel providing reader-
writer locks

Dept. of Computer Science and Engineering


Dining-Philosophers Problem

 Philosophers spend their lives alternating thinking and eating


 Don’t interact with their neighbors, occasionally try to pick up 2 chopsticks (one at a time)
to eat from bowl
 Need both to eat, then release both when done
 In the case of 5 philosophers
 Shared data
 Bowl of rice (data set)
 Semaphore chopstick [5] initialized to 1

Dept. of Computer Science and Engineering


Dining-Philosophers Problem Algorithm
 The structure of Philosopher i:
do {
wait (chopstick[i] );
wait (chopStick[ (i + 1) % 5] );

// eat

signal (chopstick[i] );
signal (chopstick[ (i + 1) % 5] );

// think

} while (TRUE);
 What is the problem with this algorithm?

Dept. of Computer Science and Engineering


Dining-Philosophers Problem Algorithm (Cont.)

 Deadlock handling
 Allow at most 4 philosophers to be sitting simultaneously at the table.
 Allow a philosopher to pick up the forks only if both are available (picking must be
done in a critical section.
 Use an asymmetric solution -- an odd-numbered philosopher picks up first the left
chopstick and then the right chopstick.
 Even-numbered philosopher picks up first the right chopstick and then the left
chopstick.

 Priority Inversion – Scheduling problem when lower-priority process holds a


lock needed by higher-priority process
 Solved via priority-inheritance protocol

Dept. of Computer Science and Engineering


Problems with Semaphores

 Incorrect use of semaphore operations:

 signal (mutex) …. wait (mutex)

 wait (mutex) … wait (mutex)

 Omitting of wait (mutex) or signal (mutex) (or both)

 Deadlock and starvation are possible.

Dept. of Computer Science and Engineering


Monitors

Textbook Reference:
Operating System Concepts – 9th Edition
Silberschatz, Galvin and Gagne ©2013
Monitors
 A high-level abstraction that provides a convenient and effective mechanism for process
synchronization
 Abstract data type, internal variables only accessible by code within the procedure
 Only one process may be active within the monitor at a time
 But not powerful enough to model some synchronization schemes

monitor monitor-name
{
// shared variable declarations
procedure P1 (…) { …. }

procedure Pn (…) {……}

Initialization code (…) { … }


}
}

Dept. of Computer Science and Engineering


Schematic view of a Monitor

Dept. of Computer Science and Engineering


Condition Variables
 condition x, y;
 Two operations are allowed on a condition variable:
 x.wait() – a process that invokes the operation is suspended until
x.signal()
 x.signal() – resumes one of processes (if any) that invoked
x.wait()
 If no x.wait() on the variable, then it has no effect on the variable

Dept. of Computer Science and Engineering


Monitor with Condition Variables

Dept. of Computer Science and Engineering


Condition Variables Choices
 If process P invokes x.signal(), and process Q is suspended in x.wait(),
what should happen next?
 Both Q and P cannot execute in paralel.
 If Q is resumed, then P must wait
 Options include
 Signal and wait – P waits until Q either leaves the monitor or it waits for another condition
 Signal and continue – Q waits until P either leaves the monitor or it waits for another
condition
 Both have pros and cons – language implementer can decide
 Monitors implemented in Concurrent Pascal compromise
 P executing signal immediately leaves the monitor, Q is resumed

 Implemented in other languages including Mesa, C#, Java

Dept. of Computer Science and Engineering


Monitor Solution to Dining Philosophers
monitor DiningPhilosophers
{
enum { THINKING; HUNGRY, EATING) state [5] ;
condition self [5];

void pickup (int i) {


state[i] = HUNGRY;
test(i);
if (state[i] != EATING) self[i].wait;
}

void putdown (int i) {


state[i] = THINKING;
// test left and right neighbors
test((i + 4) % 5);
test((i + 1) % 5);
}

Dept. of Computer Science and Engineering


Solution to Dining Philosophers (Cont.)
void test (int i) {
if ((state[(i + 4) % 5] != EATING) &&
(state[i] == HUNGRY) &&
(state[(i + 1) % 5] != EATING) ) {
state[i] = EATING ;
self[i].signal () ;
}
}

initialization_code() {
for (int i = 0; i < 5; i++)
state[i] = THINKING;
}
}

Dept. of Computer Science and Engineering


Solution to Dining Philosophers (Cont.)

 Each philosopher i invokes the operations pickup() and putdown() in


the following sequence:

DiningPhilosophers.pickup(i);

EAT

DiningPhilosophers.putdown(i);

 No deadlock, but starvation is possible

Dept. of Computer Science and Engineering


Monitor Implementation Using Semaphores

 Variables

semaphore mutex; // (initially = 1)


semaphore next; // (initially = 0)
int next_count = 0;

 Each procedure F will be replaced by

wait(mutex);

body of F;

if (next_count > 0)
signal(next)
else
signal(mutex);

 Mutual exclusion within a monitor is ensured

Dept. of Computer Science and Engineering


Monitor Implementation – Condition Variables

 For each condition variable x, we have:

semaphore x_sem; // (initially = 0)


int x_count = 0;

 The operation x.wait can be implemented as:

x_count++;
if (next_count > 0)
signal(next);
else
signal(mutex);
wait(x_sem);
x_count--;

Dept. of Computer Science and Engineering


Monitor Implementation (Cont.)

 The operation x.signal can be implemented as:

if (x_count > 0) {
next_count++;
signal(x_sem);
wait(next);
next_count--;
}

Dept. of Computer Science and Engineering


Resuming Processes within a Monitor

 If several processes queued on condition x, and x.signal() executed, which


should be resumed?
 FCFS frequently not adequate
 conditional-wait construct of the form x.wait(c)
 Where c is priority number
 Process with lowest number (highest priority) is scheduled next

Dept. of Computer Science and Engineering


Single Resource allocation
 Allocate a single resource among competing processes using priority
numbers that specify the maximum time a process plans to use the
resource

R.acquire(t);
...
access the resurce;
...

R.release;

 Where R is an instance of type ResourceAllocator

Dept. of Computer Science and Engineering


A Monitor to Allocate Single Resource
monitor ResourceAllocator
{
boolean busy;
condition x;
void acquire(int time) {
if (busy)
x.wait(time);
busy = TRUE;
}
void release() {
busy = FALSE;
x.signal();
}
initialization code() {
busy = FALSE;
}
}

Dept. of Computer Science and Engineering


Deadlocks

Textbook Reference:
Operating System Concepts – 9th Edition
Silberschatz, Galvin and Gagne ©2013
Deadlocks
 System Model
 Deadlock Characterization
 Methods for Handling Deadlocks
 Deadlock Prevention
 Deadlock Avoidance
 Deadlock Detection
 Recovery from Deadlock

a waiting process is never again able to change state, because the resources it has
requested are held by other waiting processes. This situation is called a deadlock.

Dept. of Computer Science and Engineering


System Model
 System consists of resources
 Resource types R1, R2, . . ., Rm
CPU cycles, memory space, I/O devices

 Each resource type Ri has Wi instances.


 Each process utilizes a resource as follows:
 request
 use
 release

Dept. of Computer Science and Engineering


Deadlock Characterization
Deadlock can arise if four conditions hold simultaneously.

 Mutual exclusion: only one process at a time can use a resource


 Hold and wait: a process holding at least one resource is waiting to acquire
additional resources held by other processes
 No preemption: a resource can be released only voluntarily by the process
holding it, after that process has completed its task
 Circular wait: there exists a set {P0, P1, …, Pn} of waiting processes such that
P0 is waiting for a resource that is held by P1, P1 is waiting for a resource that is
held by P2, …, Pn–1 is waiting for a resource that is held by Pn, and Pn is waiting
for a resource that is held by P0.

Dept. of Computer Science and Engineering


Deadlock with Mutex Locks
 Deadlocks can occur via system calls, locking, etc.
 Let’s see how deadlock can occur in a multithreaded Pthread program using
mutex locks.
 The pthread_mutex_init() function initializes an unlocked mutex.
 Mutex locks are acquired and released using pthread_mutex_lock() and
pthread_mutex_unlock(), respectively.
 If a thread attempts to acquire a locked mutex, the call to pthread_mutex_lock()
blocks the thread until the owner of the mutex lock invokes
pthread_mutex_unlock().

Dept. of Computer Science and Engineering


Deadlock with Mutex Locks

Dept. of Computer Science and Engineering


Deadlock with Mutex Locks

Dept. of Computer Science and Engineering


Deadlock with Mutex Locks

Dept. of Computer Science and Engineering


Deadlock with Mutex Locks
 In this example, thread one attempts to acquire the mutex locks in the order
 (1) first_mutex, (2) second_mutex,
 while thread two attempts to acquire the mutex locks in the order (1)
second_mutex, (2) first_mutex.
 Deadlock is possible if thread one acquires first_mutex while thread two
acquires second_mutex.

Dept. of Computer Science and Engineering


Deadlock with Mutex Locks
 Note that, even though deadlock is possible, it will not occur if thread one can
acquire and release the mutex locks for first_mutex and second_mutex before
thread two attempts to acquire the locks.
 The order in which the threads run depends on how they are scheduled by the
CPU scheduler.
 This example illustrates a problem with handling deadlocks:
 it is difficult to identify and test for deadlocks that may occur only under certain
scheduling circumstances.

Dept. of Computer Science and Engineering


Resource-Allocation Graph
A set of vertices V and a set of edges E.
 V is partitioned into two types:
 P = {P1, P2, …, Pn}, the set consisting of all the processes in the system

 R = {R1, R2, …, Rm}, the set consisting of all resource types in the
system

 request edge – directed edge Pi  Rj

 assignment edge – directed edge Rj  Pi

Dept. of Computer Science and Engineering


Resource-Allocation Graph (Cont.)
 Process

 Resource Type with 4 instances

 Pi requests instance of Rj
Pi
Rj

 Pi is holding an instance of Rj

Pi
Rj

Dept. of Computer Science and Engineering


Example of a Resource Allocation Graph

Dept. of Computer Science and Engineering


Resource Allocation Graph With A Deadlock

Dept. of Computer Science and Engineering


Graph With A Cycle But No Deadlock

Dept. of Computer Science and Engineering


Basic Facts

 If graph contains no cycles  no deadlock


 If graph contains a cycle 
 if only one instance per resource type, then deadlock
 if several instances per resource type, possibility of deadlock

Dept. of Computer Science and Engineering


Methods for Handling Deadlocks
 Ensure that the system will never enter a deadlock state:
 Deadlock prevention
 Deadlock avoidance
 Allow the system to enter a deadlock state and then recover
 Ignore the problem and pretend that deadlocks never occur in the
system; used by most operating systems, including UNIX

Dept. of Computer Science and Engineering


Deadlock Prevention

Restrain the ways request can be made


 Mutual Exclusion – not required for sharable resources (e.g., read-only files);
must hold for non-sharable resources
 Hold and Wait – must guarantee that whenever a process requests a resource,
it does not hold any other resources
 Require process to request and be allocated all its resources before it begins
execution, or allow process to request resources only when the process has none
allocated to it.
 Low resource utilization; starvation possible

Dept. of Computer Science and Engineering


Deadlock Prevention (Cont.)

 No Preemption –
 If a process that is holding some resources requests another resource that cannot be
immediately allocated to it, then all resources currently being held are released
 Preempted resources are added to the list of resources for which the process is waiting
 Process will be restarted only when it can regain its old resources, as well as the new ones
that it is requesting
 we preempt the desired resources from the waiting process and allocate them to the
requesting process. If the resources are neither available nor held by a waiting process, the
requesting process must wait.
 Circular Wait – impose a total ordering of all resource types, and require that each
process requests resources in an increasing order of enumeration

Dept. of Computer Science and Engineering


Dept. of Computer Science and Engineering


Deadlock Example
/* thread one runs in this function */
void *do_work_one(void *param)
{

pthread_mutex_lock(&first_mutex);
pthread_mutex_lock(&second_mutex);
/** * Do some work */
pthread_mutex_unlock(&second_mutex);
pthread_mutex_unlock(&first_mutex);
pthread_exit(0);
}
/* thread two runs in this function */
void *do_work_two(void *param)
{

pthread_mutex_lock(&second_mutex);
pthread_mutex_lock(&first_mutex);
/** * Do some work */
pthread_mutex_unlock(&first_mutex);
pthread_mutex_unlock(&second_mutex);
pthread_exit(0);
}

Dept. of Computer Science and Engineering


Deadlock Example with Lock Ordering

void transaction(Account from, Account to, double amount)


{
mutex lock1, lock2;
lock1 = get_lock(from);
lock2 = get_lock(to);
acquire(lock1);
acquire(lock2);
withdraw(from, amount);
deposit(to, amount);
release(lock2);
release(lock1);
}

• Transactions 1 and 2 execute concurrently.


• Transaction 1 transfers $25 from account A to account B, and
• Transaction 2 transfers $50 from account B to account A

Dept. of Computer Science and Engineering


Deadlock Avoidance
Requires that the system has some additional a priori information
available

 Simplest and most useful model requires that each process declare the
maximum number of resources of each type that it may need
 The deadlock-avoidance algorithm dynamically examines the resource-
allocation state to ensure that there can never be a circular-wait condition
 Resource-allocation state is defined by the number of available and allocated
resources, and the maximum demands of the processes

Dept. of Computer Science and Engineering


Safe State

 When a process requests an available resource, system must decide if


immediate allocation leaves the system in a safe state
 System is in safe state if there exists a sequence <P1, P2, …, Pn> of ALL the
processes in the systems such that for each Pi, the resources that Pi can still
request can be satisfied by currently available resources + resources held by
all the Pj, with j < I
 That is:
 If Pi resource needs are not immediately available, then Pi can wait until all Pj have
finished
 When Pj is finished, Pi can obtain needed resources, execute, return allocated
resources, and terminate
 When Pi terminates, Pi +1 can obtain its needed resources, and so on

Dept. of Computer Science and Engineering


Basic Facts

 If a system is in safe state  no deadlocks

 If a system is in unsafe state  possibility of deadlock

 Avoidance  ensure that a system will never enter an unsafe state.

Dept. of Computer Science and Engineering


Safe, Unsafe, Deadlock State
• To illustrate, we consider a system with twelve
magnetic tape drives and three processes: P0 ,
P1 , and P2 .

• Process P0 requires ten tape drives, process P1


may need as many as four tape drives, and
process P2 may need up to nine tape drives.

• Suppose that, at time t0 , process P0 is holding


five tape drives, process P1 is holding two tape
drives, and process P2 is holding two tape
drives.

• A system can go from a safe state to an unsafe


state. Suppose that, at time t1 , process P2
requests and is allocated one more tape drive.
The system is no
longer in a safe state.

Dept. of Computer Science and Engineering


Avoidance Algorithms
 Single instance of a resource type
 Use a resource-allocation graph

 Multiple instances of a resource type


 Use the banker’s algorithm

Dept. of Computer Science and Engineering


Resource-Allocation Graph Scheme

 Claim edge Pi  Rj indicated that process Pj may request resource Rj; represented by
a dashed line.
 Claim edge converts to request edge when a process requests a resource.
 Request edge converted to an assignment edge when the resource is allocated to the
process.
 When a resource is released by a process, assignment edge reconverts to a claim
edge.
 Resources must be claimed a priori in the system.

Dept. of Computer Science and Engineering


Resource-Allocation Graph

Dept. of Computer Science and Engineering


Unsafe State In Resource-Allocation Graph

Dept. of Computer Science and Engineering


Resource-Allocation Graph Algorithm

 Suppose that process Pi requests a resource Rj


 The request can be granted only if converting the request edge to an assignment
edge does not result in the formation of a cycle in the resource allocation graph

Dept. of Computer Science and Engineering


Banker’s Algorithm
 Multiple instances

 Each process must a priori claim maximum use

 When a process requests a resource it may have to wait

 When a process gets all its resources it must return them in a finite amount of
time

Dept. of Computer Science and Engineering


Data Structures for the Banker’s Algorithm

Let n = number of processes, and m = number of resources types.


 Available: Vector of length m. If available [j] = k, there are k instances of
resource type Rj available

 Max: n x m matrix. If Max [i,j] = k, then process Pi may request at most k


instances of resource type Rj

 Allocation: n x m matrix. If Allocation[i,j] = k then Pi is currently allocated k


instances of Rj

 Need: n x m matrix. If Need[i,j] = k, then Pi may need k more instances of Rj to


complete its task

Need [i,j] = Max[i,j] – Allocation [i,j]

Dept. of Computer Science and Engineering


Safety Algorithm
1. Let Work and Finish be vectors of length m and n, respectively. Initialize:
Work = Available
Finish [i] = false for i = 0, 1, …, n- 1

2. Find an i such that both:


(a) Finish [i] = false
(b) Needi  Work
If no such i exists, go to step 4

3. Work = Work + Allocationi


Finish[i] = true
go to step 2

4. If Finish [i] == true for all i, then the system is in a safe state

Dept. of Computer Science and Engineering


Resource-Request Algorithm for Process Pi

Requesti = request vector for process Pi. If Requesti [j] = k then process Pi wants
k instances of resource type Rj
1. If Requesti  Needi go to step 2. Otherwise, raise error condition, since process has
exceeded its maximum claim
2. If Requesti  Available, go to step 3. Otherwise Pi must wait, since resources are not
available
3. Pretend to allocate requested resources to Pi by modifying the state as follows:
Available = Available – Requesti;

Allocationi = Allocationi + Requesti;

Needi = Needi – Requesti;


 If safe  the resources are allocated to Pi
 If unsafe  Pi must wait, and the old resource-allocation state is restored

Dept. of Computer Science and Engineering


Example of Banker’s Algorithm

 5 processes P0 through P4;


3 resource types:
A (10 instances), B (5instances), and C (7 instances)
 Snapshot at time T0:
Allocation Max Available
ABC ABC ABC
P0 010 753 332
P1 2 0 0 322
P2 3 0 2 902
P3 2 1 1 222
P4 0 0 2 433

Dept. of Computer Science and Engineering


Example (Cont.)
 The content of the matrix Need is defined to be Max – Allocation

Need
ABC
P0 7 4 3
P1 1 2 2
P2 6 0 0
P3 0 1 1
P4 4 3 1

 The system is in a safe state since the sequence < P1, P3, P4, P2, P0> satisfies
safety criteria

Dept. of Computer Science and Engineering


Example: P1 Request (1,0,2)
 Check that Request  Available (that is, (1,0,2)  (3,3,2)  true
Allocation Need Available
ABC ABC ABC
P0 010 743 230
P1 302 020
P2 302 600
P3 211 011
P4 002 431

 Executing safety algorithm shows that sequence < P1, P3, P4, P0, P2> satisfies safety
requirement

 Can request for (3,3,0) by P4 be granted?

 Can request for (0,2,0) by P0 be granted?

Dept. of Computer Science and Engineering


Deadlock Detection

 Allow system to enter deadlock state

 Detection algorithm

 Recovery scheme

Dept. of Computer Science and Engineering


Single Instance of Each Resource Type

 Maintain wait-for graph


 Nodes are processes
 Pi  Pj if Pi is waiting for Pj

 Periodically invoke an algorithm that searches for a cycle in the graph.


 If there is a cycle, there exists a deadlock
 An algorithm to detect a cycle in a graph requires an order of n2 operations, where n
is the number of vertices in the graph

Dept. of Computer Science and Engineering


Resource-Allocation Graph and Wait-for Graph

Resource-Allocation Graph Corresponding wait-for graph

Dept. of Computer Science and Engineering


Several Instances of a Resource Type
 Available: A vector of length m indicates the number of available resources of
each type
 Allocation: An n x m matrix defines the number of resources of each type
currently allocated to each process
 Request: An n x m matrix indicates the current request of each process. If
Request [i][j] = k, then process Pi is requesting k more instances of resource type
Rj.

Dept. of Computer Science and Engineering


Detection Algorithm

1. Let Work and Finish be vectors of length m and n, respectively Initialize:


(a) Work = Available
(b) For i = 1,2, …, n, if Allocationi  0, then
Finish[i] = false; otherwise, Finish[i] = true

2. Find an index i such that both:


(a) Finish[i] == false
(b) Requesti  Work

If no such i exists, go to step 4

Dept. of Computer Science and Engineering


Detection Algorithm (Cont.)
3. Work = Work + Allocationi
Finish[i] = true
go to step 2

4. If Finish[i] == false, for some i, 1  i  n, then the system is in deadlock state.


Moreover, if Finish[i] == false, then Pi is deadlocked

Algorithm requires an order of O(m x n2) operations to detect


whether the system is in deadlocked state

Dept. of Computer Science and Engineering


Example of Detection Algorithm
 Five processes P0 through P4; three resource types
A (7 instances), B (2 instances), and C (6 instances)

 Snapshot at time T0:


Allocation Request Available
ABC ABC ABC
P0 010 000 000
P1 200 202
P2 303 000
P3 211 100
P4 002 002

 Sequence <P0, P2, P3, P1, P4> will result in Finish[i] = true for all i

Dept. of Computer Science and Engineering


Example (Cont.)

 P2 requests an additional instance of type C


Request
ABC
P0 0 0 0
P1 2 0 2
P2 0 0 1
P3 1 0 0
P4 0 0 2

 State of system?
 Can reclaim resources held by process P0, but insufficient resources to fulfill other
processes; requests
 Deadlock exists, consisting of processes P1, P2, P3, and P4

Dept. of Computer Science and Engineering


Detection-Algorithm Usage
 When, and how often, to invoke depends on:
 How often a deadlock is likely to occur?
 How many processes will need to be rolled back?
 one for each disjoint cycle

 Of course, invoking the deadlock-detection algorithm for every resource request


will incur considerable overhead in computation time. A less expensive alternative
is simply to invoke the algorithm at defined intervals—for example, once per hour
or whenever CPU utilization drops below 40 percent.
 If detection algorithm is invoked arbitrarily, there may be many cycles in the
resource graph and so we would not be able to tell which of the many deadlocked
processes “caused” the deadlock.
 we can invoke the deadlock-detection algorithm every time a request for allocation
cannot be granted immediately.

Dept. of Computer Science and Engineering


Recovery from Deadlock: Process Termination

 Abort all deadlocked processes

 Abort one process at a time until the deadlock cycle is eliminated

 In which order should we choose to abort?


1. Priority of the process
2. How long process has computed, and how much longer to completion
3. Resources the process has used
4. Resources process needs to complete
5. How many processes will need to be terminated
6. Is process interactive or batch?

Dept. of Computer Science and Engineering


Recovery from Deadlock: Resource Preemption

 Selecting a victim – minimize cost

 Rollback – return to some safe state, restart process for that state

 Starvation – same process may always be picked as victim, include


number of rollback in cost factor

Dept. of Computer Science and Engineering

You might also like