1 / 60

Monitors, Condition Variables, and Readers-Writers

Learn about monitors, condition variables, and how they are used to solve the readers-writers problem. Understand the concepts, operations, and examples of using locks and condition variables in multi-threaded applications.

hclemons
Download Presentation

Monitors, Condition Variables, and Readers-Writers

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. Monitors, Condition Variables, and Readers-Writers Andy Wang Operating Systems COP 4610 / CGS 5765

  2. Motivation for Monitors • Semaphores are a big step from the low-level loads and stores • However, semaphores are used for both mutual exclusion and scheduling • The idea of monitors is to separate these two concerns

  3. Monitor Defined • Monitor: a lock + condition variables • Lock: provides mutual exclusion to shared data • Condition variable: provides a queue for waiting threads inside a critical section

  4. Locks • A lock provides two operations: • Lock::Acquire() • Wait until the lock is free, then grab it • Lock::Release() • Unlock, wake up anyone waiting to Acquire • A lock is initially free

  5. More on Locks • Always acquire a lock before accessing a shared data structure • Always release the lock after finishing with the shared data structure

  6. An Example of Using Locks AddToBuffer() { Lock.Acquire(); // put 1 item to the buffer Lock.Release(); } RemoveFromBuffer() { Lock.Acquire(); // if something in the buffer // remove 1 item form the buffer Lock.Release(); return item; }

  7. Condition Variables • We need additional mechanisms to wait inside locked regions • However, holding the lock while waiting prevents other threads from entering the locked region • Condition variables make it possible to sleep inside a critical section • Atomically release the lock & go to sleep

  8. Condition Variables • Each condition variable • Consists of a queue of threads • Provides three operations • Wait(); • Atomically release the lock and go to sleep • Reacquire lock on return • Signal(); • Wake up one waiting thread, if any • Broadcast(); • Wake up all waiting threads

  9. Condition Variables • Note • The three operations can only be used inside locked regions

  10. An Example of Using Condition Variables AddToBuffer() { lock.Acquire(); // put 1 item to the buffer condition.Broadcast(&lock); // move threads from the // wait queue to the ready queue // do something else lock.Release(); } RemoveFromBuffer() { lock.Acquire(); while nothing in the buffer { condition.Wait(&lock); // implicit lock release // implicit lock acquire } lock.Release(); return item; }

  11. Hoare vs. Mesa Monitors • Hoare Monitors (used in most textbooks) • Signal() transfers the CPU directly to a waiting thread

  12. Mesa vs. Hoare Monitors • Mesa Monitors (used in most real operating systems) • Signal() only puts a waiting thread on the scheduler’s ready queue • By the time the waken thread gets the CPU, the waiting condition may no longer be true and needs to be retested

  13. Readers-Writers Problem • Commonly seen in database applications • Readers never modify the database • Writers read and modify the database • We want one writer at a time, but many readers at the same time

  14. Constraints • A reader should wait when a writer is accessing or waiting for the database • Condition okToRead • A writer should wait when there is a reader or writer accessing the database • Condition okToWrite • A reader or a writer should wait when someone is modifying global states • Lock lock

  15. Basic Structure of the Solution • Reader • Wait until no writers • Access database • Wake up waiting writers • Writer • Wait until no active readers or writers • Access database • Wake up waiting readers or writers

  16. Developing the Solution • Global states: activeReaders = 0; activeWriters = 0; waitingReaders = 0; waitingWriters = 0; Condition okToRead = NULL; Condition okToWrite = NULL; Lock lock = FREE;

  17. Reader() { lock.Acquire(); ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; lock.Release(); } Writer() { lock.Acquire(); ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release(); } Put in Locks and Some Global States

  18. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; lock.Release(); } Writer() { lock.Acquire(); ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release(); } Add the Wait Condition for Reader

  19. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release(); } Add the Wait Condition for Writer

  20. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; lock.Release(); } Add the Signal Condition for Reader

  21. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Add the Signal Condition for Writer

  22. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  23. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  24. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  25. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  26. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  27. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  28. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  29. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  30. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  31. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  32. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  33. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  34. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  35. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  36. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  37. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  38. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  39. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  40. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  41. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  42. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  43. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  44. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  45. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  46. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  47. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  48. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  49. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

  50. Reader() { lock.Acquire(); while (activeWriters > 0 || waitingWriters > 0) { ++waitingReaders; okToRead.Wait(&lock); --waitingReaders; } ++activeReaders; lock.Release(); // access database lock.Acquire(); --activeReaders; if (activeReaders == 0 && waitingWriters > 0) { okToWrite.Signal(&lock); } lock.Release(); } Writer() { lock.Acquire(); while (activeWriters > 0 || activeReaders > 0) { ++waitingWriters; okToWrite.Wait(&lock); --waitingWriters; } ++activeWriters; lock.Release(); // access database lock.Acquire(); --activeWriters; if (waitingWriters > 0) { okToWrite.Signal(&lock); } else if (waitingReaders > 0) { okToRead.Broadcast(&lock); } lock.Release(); } Code Demonstration

More Related