concurrent programming james adkison 02/28/2008. what is concurrency? “happens-before relation –...
TRANSCRIPT
What is concurrency?
“happens-before relation – A happens before B if A and B belong to the same process and A occurred before B; or A is the sending of a message and B is the receiving of that message” (Deitel)
What is concurrency?
“concurrent – Two events are concurrent if it cannot be determined which event occurred earlier by following the happens-before relation” (Deitel)
Assumptions
Using a single processor system Working with threads, not processes Working with only two threads Any level of interleaving is possible Machine-level instructions are atomic (i.e.
are executed indivisibly)
Why Use Concurrency?
Improved throughputthroughput – Amount of work performed per
unit time. Improved responsiveness
e.g. responsive GUI Appropriate / Required for problem domain
Concurrency Example:Producer / Consumer Producer:
Writes integers 1 – 4 (in order) to a shared buffer and terminates
Consumer:Reads and sums the integers 1 – 4 from the
shared bufferDisplay the sum total and terminate
Producer / Consumer – Output
Correct (Desired) Output:Producer writes 1
Consumer reads 1
Producer writes 2
Consumer reads 2
Producer writes 3
Consumer reads 3
Producer writes 4
Terminating: Producer.
Consumer reads 4
Consumer read values totaling: 10.
Terminating: Consumer.
Producer / Consumer – Output
Correct (Desired) Output:Producer writes 1
Consumer reads 1
Producer writes 2
Consumer reads 2
Producer writes 3
Consumer reads 3
Producer writes 4
Terminating: Producer.
Consumer reads 4
Consumer read values totaling: 10.
Terminating: Consumer.
Sample Output:Consumer reads -1
Producer writes 1
Consumer reads 1
Producer writes 2
Producer writes 3
Consumer reads 3
Consumer reads 3
Consumer reads values totaling: 6.
Terminating: Consumer.
Producer writes 4
Terminating: producer.
Critical Section (CS)
“When a thread is accessing shared modifiable data.” (Deitel)
Producer / Consumer: the shared mutable buffer
int x = 10;Thread1 Thread2
Read x Read x
Write 3xWrite -2x
Critical Section
Mutual Exclusion
“Restriction whereby execution by a thread of its critical section precludes execution by other threads of their critical sections.” (Deitel)
“Mutual exclusion is crucial to correct execution when multiple threads access shared writable data.” (Deitel)
Implementing Mutual Exclusion
A purely software solution Constraint 1:
A thread outside of its critical section can not block another thread from entering the critical section
Constraint 2:A thread must not be indefinitely postponed
from entering its critical section
Mutual Exclusion – Version 1
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Is Mutual Exclusion Guaranteed?
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Guarantees mutual exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Guarantees mutual exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Guarantees mutual exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Guarantees mutual exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Guarantees mutual exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Guarantees mutual exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Are Both Constraints Satisfied?
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Violates Constraint1
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Any new problems?
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Lockstep Synchronization Problem
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Lockstep Synchronization Problem
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 –Lockstep Synchronization Problem
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 2 );
// Critical section
threadNumber = 2;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( threadNumber == 1 );
// Critical section
threadNumber = 1;
// Outside critical section
}
...
int threadNumber = 1; // globally accessible to Thread1 and Thread2
Version 1 – Assessment
Guarantees mutual exclusion Drawbacks:
Violates constraint 1Lockstep synchronization problem
Mutual Exclusion – Version 2
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Is Constraint1 Satisfied Now?
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Obeys Constraint1
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Obeys Constraint1
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 – Does the Lockstep Synchronization Problem Persist?
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Resolves Lockstep Synchronization
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Resolves Lockstep Synchronization
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Resolves Lockstep Synchronization
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Any new problems?
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Violates Mutual Exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Violates Mutual Exclusion
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Version 2 –Resolves Lockstep Synchronization
// Thread1
...
while (!done) {
// Enter mutual exclusion
while ( t2Inside );
t1Inside = true;
// Critical section
t1Inside = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
while ( t1Inside );
t2Inside = true;
// Critical section
t2Inside = false;
// Outside critical section
}
...
boolean t1Inside = false; // t1Inside and t2Inside are globally
boolean t2Inside = false; // accessible to Thread1 and Thread2
Mutual Exclusion – Version 3
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn );
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn );
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 3 –Any new problems?
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn );
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn );
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 3 –Introduces Deadlock
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn );
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn );
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 3 –Introduces Deadlock
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn );
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn );
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 3 –Introduces Deadlock
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn );
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn );
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 3 – Assessment
Guarantees mutual exclusion Prevents lockstep synchronization Introduces a new problem: deadlock
Mutual Exclusion – Version 4
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 4 –Any new problems?
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Mutual Exclusion –Introduces Indefinite Postponement
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Mutual Exclusion –Introduces Indefinite Postponement
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Mutual Exclusion –Introduces Indefinite Postponement
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Mutual Exclusion –Introduces Indefinite Postponement
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Mutual Exclusion –Introduces Indefinite Postponement
// Thread1
...
while (!done) {
// Enter mutual exclusion
t1WantsIn = true;
while ( t2WantsIn ) {
t1WantsIn = false;
// wait a random time
t1WantsIn = true;
}
// Critical section
t1WantsIn = false;
// Outside critical section
}
...
// Thread2
...
while (!done) {
// Enter mutual exclusion
t2WantsIn = true;
while ( t1WantsIn ) {
t2WantsIn = false;
// wait a random time
t2WantsIn = true;
}
// Critical section
t2WantsIn = false;
// Outside critical section
}
...
boolean t1WantsIn = false; // t1WantsIn and t2WantsIn are globally
boolean t2WantsIn = false; // accessible to Thread1 and Thread2
Version 4 – Assessment
Guarantees mutual exclusion Prevents lockstep synchronization Prevents deadlock Introduces a new problem: indefinite
postponement
Mutual Exclusion –Dekker’s Algorithm “An elegant software implementation of
mutual exclusion was first presented by Dekker, a Dutch mathematician” (Deitel)
Dijkstra’s development ofDekker’s Algorithm
// Thread1
while (!done) {
t1WantsIn = true;
while ( t2WantsIn ) {
if ( favoredThread == 2 ) {
t1WantsIn = false;
while (favoredThread == 2);
t1WantsIn = true;
}
}
// Critical section
favoredThread = 2;
t1WantsIn = false;
// Outside critical section
}
int favoredThread = 1; // favoredThread, t1WantsIn, and t2WantsIn
boolean t1WantsIn = false; // are globally accessible
boolean t2WantsIn = false; // to Thread1 and Thread2
// Thread1
while (!done) {
t2WantsIn = true;
while ( t1WantsIn ) {
if ( favoredThread == 1 ) {
t2WantsIn = false;
while (favoredThread == 1);
t2WantsIn = true;
}
}
// Critical section
favoredThread = 1;
t2WantsIn = false;
// Outside critical section
}
Dekker’s Algorithm – Assessment
Guarantees mutual exclusion Prevents lockstep synchronization Prevents deadlock Prevents indefinite postponement
Peterson’s Algorithm
“In 1981, G. L. Peterson published a simpler algorithm for enforcing two-process mutual exclusion with busy waiting.” (Deitel)
Peterson’s Algorithm
// Thread1
while (!done) {
t1WantsIn = true;
favoredThread = 2;
while ( t2WantsIn
&& favoredThread == 2 );
// Critical section
t1WantsIn = false;
// Outside critical section
}
// Thread2
while (!done) {
t2WantsIn = true;
favoredThread = 1;
while ( t1WantsIn )
&& favoredThread == 1 );
// Critical section
t2WantsIn = false;
// Outside critical section
}
int favoredThread = 1; // favoredThread, t1WantsIn, and t2WantsIn
boolean t1WantsIn = false; // are globally accessible
boolean t2WantsIn = false; // to Thread1 and Thread2
Mutual Exclusion Primitives
Software: 2-Thread Mutual ExclusionDekker / Dijkstra – Dekker’s AlgorithmG. L. Peterson – Peterson’s Algorithm
n-Thread Mutual ExclusionLeslie Lamport – Lamport’s Bakery Algorithm
Can be done in Hardware alsoSemaphores – Dijkstra
Mutual Exclusion Primitives
The methods we’ve seen so far are very basic and are error prone.
Being so primitive, solving more complex concurrency problems becomes very challenging
Conclusion, higher-level – simpler mutual exclusion structures are needed
James AdkisonConcurrent Programming Homework Questions
1. What’s the difference between deadlock and indefinite postponement (livelock)? Hint: Definitions are provided but were not shown during the presentation.
2. [True or False] When 8 and only 8 threads perform read-only operations on a immutable shared resource mutual exclusion must be guaranteed?
3. [True or False] Mutual exclusion must be guaranteed when threads share a resource that is mutable?