concurrent programming james adkison 02/28/2008. what is concurrency? “happens-before relation –...

62
Concurrent Programming James Adkison 02/28/2008

Upload: ari-tims

Post on 14-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

ConcurrentProgramming

James Adkison

02/28/2008

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

Version 2 – Assessment

Eliminates lockstep synchronization

Does NOT guarantee mutual exclusion

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?

Works Cited

Deitel, Harvey M., Paul J. Deitel, and David R. Choffnes. Operating Systems Thrid Edition. New Jersey: Pearson Education, Inc., 2004