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.

Slides:



Advertisements
Similar presentations
1 Interprocess Communication 1. Ways of passing information 2. Guarded critical activities (e.g. updating shared data) 3. Proper sequencing in case of.
Advertisements

Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Operating Systems Part III: Process Management (Process Synchronization)
1 Chapter 5 Concurrency: Mutual Exclusion and Synchronization Principals of Concurrency Mutual Exclusion: Hardware Support Semaphores Readers/Writers Problem.
 Read about Therac-25 at  [  [
Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Operating Systems: A Modern Perspective, Chapter 8 Slide 8-1 Copyright © 2004 Pearson Education, Inc.
Ch 7 B.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Process Synchronization Continued 7.2 The Critical-Section Problem.
Previously… Processes –Process States –Context Switching –Process Queues Threads –Thread Mappings Scheduling –FCFS –SJF –Priority scheduling –Round Robin.
Chapter 6: Process Synchronization
Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edition Chapter 5: Process Synchronization.
5.1 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts with Java – 8 th Edition Chapter 5: CPU Scheduling.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
China’s Software Industry August 2006 Instructor: Hengming Zou, Ph.D.
1 Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Operating Systems CMPSC 473 Mutual Exclusion Lecture 13: October 12, 2010 Instructor: Bhuvan Urgaonkar.
CS444/CS544 Operating Systems Synchronization 2/16/2006 Prof. Searleman
Concurrency.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
1 Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Chapter 2: Processes Topics –Processes –Threads –Process Scheduling –Inter Process Communication (IPC) Reference: Operating Systems Design and Implementation.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization
Chapter 6: Process Synchronization. Outline Background Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores Classic Problems.
Chapter 6: Process Synchronization. 6.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts – 7 th Edition, Feb 8, 2005 Objectives Understand.
Silberschatz, Galvin and Gagne ©2007 Operating System Concepts with Java – 7 th Edition, Nov 15, 2006 Process Synchronization (Or The “Joys” of Concurrent.
Chapter 2.3 : Interprocess Communication
02/23/2004CSCI 315 Operating Systems Design1 Process Synchronization Notice: The slides for this lecture have been largely based on those accompanying.
02/17/2010CSCI 315 Operating Systems Design1 Process Synchronization Notice: The slides for this lecture have been largely based on those accompanying.
Instructor: Umar KalimNUST Institute of Information Technology Operating Systems Process Synchronization.
02/19/2007CSCI 315 Operating Systems Design1 Process Synchronization Notice: The slides for this lecture have been largely based on those accompanying.
Adopted from and based on Textbook: Operating System Concepts – 8th Edition, by Silberschatz, Galvin and Gagne Updated and Modified by Dr. Abdullah Basuhail,
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
1 Lecture 9: Synchronization  concurrency examples and the need for synchronization  definition of mutual exclusion (MX)  programming solutions for.
Concurrency, Mutual Exclusion and Synchronization.
Process Synchronization Continued 7.2 Critical-Section Problem 7.3 Synchronization Hardware 7.4 Semaphores.
6.3 Peterson’s Solution The two processes share two variables: Int turn; Boolean flag[2] The variable turn indicates whose turn it is to enter the critical.
Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Silberschatz, Galvin and Gagne  Operating System Concepts Chapter 7: Process Synchronization Background The Critical-Section Problem Synchronization.
Concurrency: Mutual Exclusion and Synchronization Chapter 5.
1 Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
1 Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Chapter 6: Process Synchronization. 6.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts Module 6: Process Synchronization Background The.
Synchronicity Introduction to Operating Systems: Module 5.
Operating Systems CSE 411 CPU Management Dec Lecture Instructor: Bhuvan Urgaonkar.
Rensselaer Polytechnic Institute CSCI-4210 – Operating Systems David Goldschmidt, Ph.D.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
Process Synchronization CS 360. Slide 2 CS 360, WSU Vancouver Process Synchronization Background The Critical-Section Problem Synchronization Hardware.
Process Synchronization. Objectives To introduce the critical-section problem, whose solutions can be used to ensure the consistency of shared data To.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 6: Process Synchronization.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edition Chapter 5: Process Synchronization.
Homework-6 Questions : 2,10,15,22.
Chapter 6 Synchronization Dr. Yingwu Zhu. The Problem with Concurrent Execution Concurrent processes (& threads) often access shared data and resources.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Process Synchronization: Semaphores
Background on the need for Synchronization
Chapter 5: Process Synchronization
Concurrency: Mutual Exclusion and Synchronization
Semaphore Originally called P() and V() wait (S) { while S <= 0
Lecture 2 Part 2 Process Synchronization
Concurrency: Mutual Exclusion and Process Synchronization
CSE 542: Operating Systems
CSE 542: Operating Systems
Operating Systems {week 10}
Presentation transcript:

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