Chapter 5 - Asynchronous Concurrent Execution: Modified by D. Khaled W. Mahmoud 2009/2010
Chapter 5 - Asynchronous Concurrent Execution: Modified by D. Khaled W. Mahmoud 2009/2010
5.1 Introduction
5.1 Introduction
• Concurrent execution
– More than one thread exists in system at once
– Can execute independently or in cooperation
• Asynchronous execution
• Threads generally independent
• Must occasionally communicate or synchronize
• Complex and difficult to manage such interactions
• Example
– two threads concurrently increment the value of a specific
variable by using the following instructions:
• Read the variable
• Inc by 1
• Write the variable
– Due to quantum expire, the first thread loses the processor (after
executing the second line and before writing the value).
– The second thread executes the three instructions, and then
switch back to the first thread.
• What will be the value of this variable?
• Version one.
• Version two.
• Version three.
• Version four.
• Final version/Dekker’s Algorithm.
• Second version
– Removes lockstep synchronization
– Violates mutual exclusion
• Thread could be preempted while updating flag variable
– Not an appropriate solution
• What happens if both t1Inside and t2Inside are false and both
threads attempt to enter their critical section at the same time?
– t1 tests the value of t2Inside
– t1 lose processor before executing t1Inside=true
– t2 now is executed and enter its CS
– T1 return back and enter its critical section
• i.e. while a process is testing the while condition to set a flag that it
is inside its CS , there is enough time for the other process to test
its flag and slip into its CS.
• Third version
– Set critical section flag before entering critical section test
• Once again guarantees mutual exclusion
– Introduces possibility of deadlock
• It is possible for the following situation to happen:
– thread 1: set t1WantToEnter = true;
– thread 2: set t2WantToEnter = true;
– Thread 1 and 2 will loop forever in the while statement
– Neither would ever be able to break out of loop
– Not a solution to the mutual exclusion problem
Replace the variables t1Inside and t2Inside with the two variables:
boolean t1WantToEnter = false; boolean t2WantToEnter = false;
tiWantToEnter = true indicates that thread i desires to enter the CS.
• Fourth version
– Sets flag to false for small periods of time to yield control
– Solves previous problems, introduces indefinite postponement
• Both threads could set flags to same values at same time (same
speed -- unlikely but possible)
Thread 1 Thread 2
while(true){ while(true){
t1WantToEnter=true; t2WantToEnter=true;
while(t2WantToEnter) { while(t1WantToEnter) {
if(favouredThread==2){ if(favouredThread==1)
t1WantToEnter=false; t2WantToEnter=false;
while(favouredThread==2) while(favouredThread==1)
{wait;} {wait;}
t1WantToEnter=true; t2WantToEnter=true;
} } } }
critical section; critical section;
favouredThread=2; favouredThread=1;
t1WantToEnter=false; t2WantToEnter=false;
non-critical section; non-critical section;
} }
5.6 Semaphores
• Semaphores
– A semaphore is an integer protected variable that, apart from
initialization, is accessed only through two standard operations:
P(wait) and V(signal)
• Binary semaphores can assume only the value 0 or
the value 1.
• Semaphores can be implemented in software or
hardware, but they are commonly implemented in the
nucleus of the O.S
5.6 Semaphores
Global variables:
• Semaphore valueProduced for the “value has been produced”
event. It is initialized to 0.
• Semaphore valueConsumed for the “value has been
consumed” event. It is initialized to 1.
• int sharedValue is a variable shared by both producer and
consumer threads.
Main(){
int nextValueProduced
While(true){
nextValueProduced = generate a new value
P(valueConsumed)
sharedValue = nextValueProduced;
V(valueProduced)
} Consumer
}
Main(){
int nextValueConsumed
Producer While(true){
P(valueProduced)
nextValueConsumed = sharedValue
V(valueConsumed);
process the value
}
}
• Counting semaphores
– Initialized with values greater than one
– Can be used to control access to a pool of identical resources
• Decrement the semaphore’s counter when taking resource from
pool
• Increment the semaphore’s counter when returning it to pool
• If no resources are available, thread is blocked until a resource
becomes available