Concurrent Programming 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 throughput throughput – 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 buffer Display 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 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; Thread1Thread2 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 1 Lockstep synchronization problem
Version 1 – Definitions “busy waiting – Form of waiting where a thread continuously test a condition that will let the thread proceed eventually; while busy waiting, a thread uses processor time” (Deitel) “lockstep synchronization – Situation where asynchronous threads execute code in strict alternation” (Deitel)
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
Version 3 – Definition “deadlock – Situation in which a process or thread is waiting for an event that will never occur and therefore cannot continue execution” (Deitel)
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
Version 4 – Definition “indefinite postponement – Situation in which a thread waits for an event that might never occur” (Deitel)
Mutual Exclusion – Dekker’s Algorithm “An elegant software implementation of mutual exclusion was first presented by Dekker, a Dutch mathematician” (Deitel)
Dijkstra’s development of Dekker’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 Exclusion Dekker / Dijkstra – Dekker’s Algorithm G. L. Peterson – Peterson’s Algorithm n-Thread Mutual Exclusion Leslie Lamport – Lamport’s Bakery Algorithm Can be done in Hardware also Semaphores – 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
Monitors Object that contains both data and procedures Allocates a serially reusable shared resource Only 1 thread can enter the monitor (mutual exclusion) Data inside monitor is only accessible within the monitor
Monitor – Definitions “serially reusable resource – Resource that may be used by only one process at a time (aka a dedicated resource)” (Deitel)
Monitors Continued Condition variables wait (conditionVariable) Thread waits outside the monitor signal (conditionVariable) A waiting thread may enter the monitor Methods: signal-and-exit signal-and-continue (Java)
Monitors Using Circular Buffers Circular Buffer (aka Bounded Buffer) Could be an array that wraps around Allows the Producer to get ahead of the Consumer without waiting Waits are necessary if the buffer becomes full or empty Efficient when Producer & Consumer execute at about the same speed
Deadlock Solutions Prevention Clean solution, but often results in poor resource utilization Avoidance Dijkstra’s Banker’s Algorithm Detection / Recovery
James Adkison Concurrent 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