1 / 16

Monitor Review and Deadlock!

This presentation by Antonio Maiorano and Paul Di Marco discusses the concept of monitors, their key attributes, and how they can be accessed by only one thread at a time. It also covers the use of condition variables and provides solutions for avoiding deadlock. The presentation emphasizes the importance of using higher-level constructs and stress testing code for deadlock prevention.

hreiber
Télécharger la présentation

Monitor Review and Deadlock!

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Monitor Review and Deadlock! Presented by: Antonio Maiorano Paul Di Marco

  2. Monitors • One can think of a monitor as another Abstract Data Type – like a structure or class – with functions and private data • The key attribute of a monitor is that it can be accessed by only one thread at a time

  3. Monitor call: … myMonitor.Foo() … Monitors are simpler! Analogous call w/o Monitors: … mutex.wait(); myObject.Foo(); mutex.signal(); … Monitor Analogy A monitor object can be thought of as an object where each access to it is protected by a mutex:

  4. A Simple Monitor monitor SharedBalance { private int balance; public SharedBalance(int amt) {balance = amt;} public credit(int amt) {balance += amt;} public debit(int amt) {balance -= amt;} }

  5. Show me the money • Let’s say we only allow someone to complete a debit transaction when there is enough money to take: SharedBalance::debit(int amt) { while(balance < amt) { } // wait for the cash balance -= amt; }

  6. Whoops! • This won’t work if a debit() call occurs when there is not enough money: • debit() waits for someone to credit the account • credit() can’t run because debit is already executing in the monitor! • > DEADLOCK! • We need to use Condition Variables…

  7. Condition Variables • Condition variables are used when: • a thread running in a monitor • encounters a condition that is not satisfied, • which can only be satisfied by another thread • Ours has 3 operations: • wait() - block on a variable, give up monitor • signal() - wake up a thread blocked on this • queue() - asks “are there any threads blocked on you?”

  8. Condition Variables • You wait on a c.v. when you want to get another thread to do something for you. This is what happens when you wait(): • It temporarily blocks you, • Hands over “ownership” of the monitor you are running in to another thread • Gives you back the “ownership” of the monitor later on…

  9. Regaining the Monitor • There are two schemes for deciding when the blocked thread will regain the monitor: • Immediately, as soon as another thread signals the condition variable, or • Later on, when the thread (that signaled) finishes executing inside the monitor

  10. Show me the money already! • Using a new member variable condVar: SharedBalance::credit(int amt) { balance += amt; condVar.signal(); } SharedBalance::debit(int amt) { while(balance < amt) { condVar.wait(); } balance -= amt; }

  11. Thread 1: alpha.Wait(); beta.Wait(); DoSomething(); beta.Signal(); alpha.Signal(); Thread 2: beta.Wait(); alpha.Wait(); DoSomething(); alpha.Signal(); beta.Signal(); Deadlock with Semaphores Semaphore alpha = new Semaphore(1); Semaphore beta = new Semaphore(1);

  12. Thread 1: alpha.Wait(); beta.Wait(); DoSomething(); beta.Signal(); alpha.Signal(); Thread 2: alpha.Wait(); beta.Wait(); DoSomething(); beta.Signal(); alpha.Signal(); A Solution Semaphore alpha = new Semaphore(1); Semaphore beta = new Semaphore(1);

  13. Things to Note • Semaphores are powerful low-level synchronization tools  they can be difficult to use • Guidelines: • Enforce strict coding standards • Use higher-level constructs if they’re available (i.e. AND-synchronization) • Stress test your code for deadlock

  14. Thread 1: // Wait for var to be set alpha.Wait(); // Use var DoSomething(var); // We’re done with var beta.Signal(); Thread 2: // Set var var = InitVal(); // Let other thread use it alpha.Signal(); // Wait until it’s used beta.Wait(); Deadlock with Events int var; // Global shared variable Event alpha = new Event(0); Event beta = new Event(0);

  15. A Couple of Solutions • Impose a total ordering system: Use a semaphore to ensure Thread 1 starts before Thread 2 OR • Use semaphores instead of events because what happens in the past counts (recall: semaphores are passive, events are active)

  16. Things to Note • With events, deadlock often occurs due to timing dependencies • Must ensure that threads start in order if timing is important • Consider using semaphores instead of events – use events only when the future is important, not the past

More Related