12 commandments of
play

12 Commandments of Monitors in Python Synchronization class BK: def - PowerPoint PPT Presentation

12 Commandments of Monitors in Python Synchronization class BK: def __init__(self): I. Thou shalt name your self.lock = Lock() VIII. Honor thy shared synchronization variables data with an invariant, properly self.hungrykid =


  1. 12 Commandments of Monitors in Python Synchronization class BK: def __init__(self): I. Thou shalt name your self.lock = Lock() VIII. Honor thy shared synchronization variables data with an invariant, properly self.hungrykid = Condition(self.lock) which your code may assume II. Thou shalt not violate holds when a lock is acquired self.nBurgers= 0 abstraction boundaries nor successfully and your code wait try to change the semantics of must make true before the synchronization primitives lock is released • releases lock when called III. Thou shalt use monitors IX. Thou shalt cover thy def kid_eat(self): and condition variables naked waits. • re-acquires lock when it returns instead of semaphores with self.lock: whenever possible X. Thou shalt guard your wait predicates in a while IV. Thou shalt not mix while self.nBurgers == 0: loop. Thou shalt never semaphores and guard a wait statement condition variables self.hungrykid.wait() with an if statement V. Thou shalt not busy wait X1. Thou shalt not split self.nBurgers = self.nBurgers - 1 predicates. VI. Thou shalt protect all shared state XII. Thou shalt help make VII. Thou shalt grab the monitor the world a better place def make_burger(self): lock upon entry to, and release for the creator ’s mighty it upon exit from, a synchronization vision. with self.lock: procedure self.nBurgers = self.nBurgers + 1 self.hungrykid.notify() � 158 � 159 Monitors in “4410 Python”: Monitors in “4410 Python”: __init__ kid_eat def kid_eat(self): Python class BK: Python with self.lock: def __init__(self): while self.nBurgers == 0: self.lock = Lock() self.hungrykid. wait() self.hungrykid = Condition(self.lock) self.nBurgers = self.nBurgers - 1 self.nBurgers= 0 def kid_eat(self): 4410 Python with self.lock: from rvr import MP, MPthread 4410 Python while (self.nBurgers.read() == 0): self.hugryKid.wait() class BurgerKingMonitor(MP): self.nBurgers.dec() def __init__(self): MP.__init__(self,None) We do this for helpful feedback: Look in the A2/doc self.lock = Lock(“monitor lock”) self.hungrykid = self.lock.Condition(“hungry kid”) • from auto-grader directory for details self.nBurgers = self.Shared(“num burgers”, 0) • from debugger and example code. � 160 � 161

  2. Readers/Writers Readers/Writers Monitor ReadersNWriters { Safety int waitingWriters=0, waitingReaders=0, activeReaders=0, activeWriters=0; Condition canRead, canWrite; (# r ≥ 0) ∧ (0 ≤ # w ≤ 1) ∧ (# r > 0) ⇒ (# w = 0)) void BeginWrite() with monitor.lock: ++waitingWriters What about fairness? while (activeWriters >0 or activeReaders >0) canWrite.wait(); the last thread to live the critical section will --waitingWriters activeWriters = 1; give priority to writers To implement this policy, one needs to keep } track of waitingWriters, waitingReaders, activeWriters, and activeReaders � 162 � 163 Readers/Writers Readers/Writers Monitor ReadersNWriters { Monitor ReadersNWriters { int waitingWriters=0, waitingReaders=0, activeReaders=0, activeWriters=0; int waitingWriters=0, waitingReaders=0, activeReaders=0, activeWriters=0; Condition canRead, canWrite; Condition canRead, canWrite; void BeginRead() void BeginWrite() void BeginWrite() with monitor.lock: with monitor.lock: with monitor.lock: ++waitingReaders ++waitingWriters ++waitingWriters while (activeWriters>0 or waitingWriters>0) while (activeWriters >0 or activeReaders >0) while (activeWriters >0 or activeReaders >0) canRead.wait(); canWrite.wait(); canWrite.wait(); --waitingReaders --waitingWriters --waitingWriters ++activeReaders activeWriters = 1; activeWriters = 1; void EndWrite() void EndWrite() with monitor.lock: with monitor.lock: activeWriters = 0 activeWriters = 0 if waitingWriters > 0 if waitingWriters > 0 canWrite.signal(); canWrite.signal(); else if waitingReaders > 0 else if waitingReaders > 0 canRead.broadcast(); canRead.broadcast(); � 164 � 165 } }

  3. Readers/Writers Barrier Synchronization Monitor ReadersNWriters { n threads divide work, run rounds of int waitingWriters=0, waitingReaders=0, activeReaders=0, activeWriters=0; computation separated by barriers Condition canRead, canWrite; void BeginRead() Common paradigm in HPC void BeginWrite() with monitor.lock: with monitor.lock: ++waitingReaders Create n threads and barrier ++waitingWriters while (activeWriters>0 or waitingWriters>0) while (activeWriters >0 or activeReaders >0) Each thread does round1() canRead.wait(); canWrite.wait(); --waitingReaders barrier.chackin() --waitingWriters ++activeReaders activeWriters = 1; Each thread does round2() barrier.checkin() void EndWrite() void EndRead() with monitor.lock: with monitor.lock: activeWriters = 0 --activeReaders; if waitingWriters > 0 if (activeReaders==0 and waitingWriters>0) canWrite.signal(); canWrite.signal(); else if waitingReaders > 0 canRead.broadcast(); � 166 � 167 } Checkin with one condition variable self.allCheckedIn = Condition(self.lock) What ’ s def checkin(): wrong with self.lock: with this? nArrived++ if nArrived < nThreads: while nArrived < nThreads: allCheckedIn.wait() else: allCheckedIn.broadcast() nArrived = 0 � 168

  4. 
 System Model Exclusive (one-at-a-time) computer resources Deadlocks: CPU, printers, memory, locks, etc. Processes Prevention, Avoidance, Acquire resource Detection, Recovery if resource is available, access is granted if not, process is blocked Use resource Release resource � 1 � 2 1 2 Deadlock Deadlock A cycle of waiting among a set of threads A cycle of waiting among a set of threads A violation of liveness A violation of liveness T 1 acquire resource 1, waits for resource 2 T 1 acquire resource 1, waits for resource 2 T 2 acquires resource 2, waits for resource 1 T 2 acquires resource 2, waits for resource 1 T 1 T 2 { { P(file_mutex) P(printer_mutex) P(printer_mutex) P(file_mutex) semaphore: file_mutex = 1 /* use resources */ /* use resources */ printer_mutex = 1 V(printer_mutex) V(file_mutex) V(file_mutex) V(printer_mutex) � 3 � 3 } } 3-1 3-2

  5. Dining Philosophers Musings on Deadlock Deadlock vs Starvation class Philosopher: chopsticks[N] = [Semaphore(1),…] Starvation: some thread’ s access to a resource is def __init__(mynum) indefinitely postponed self.id = mynum Deadlock: circular waiting for resources def eat(): right = self.id Deadlock implies Starvation, but not vice versa left = (self.id+1) % N while True: “Subject to deadlock” does not imply “Will deadlock” P(chopsticks[left]) N philosophers; N plates; N chopsticks P(chopsticks[right]) Testing is not the solution # om nom nom nom If all philosophers grab right chopstick V(chopsticks[right]) System must be deadlock-free by design deadlock! V(chopsticks[left]) Need exclusive access to two chopsticks � 4 � 5 4 5 A Graph Theoretic Model Necessary Conditions of Deadlock for Deadlock Computer system modeled as a RAG, a Deadlock possible only if all four hold directed graph G(V , E) Bounded resources A finite number of threads can use a resource; resources are finite V = {P 1 ,…,P n } ⋃ {R 1 ,…,R n } P i R j No preemption the resource is mine, MINE! (until I E = {edges from a resource to a process} ⋃ release it) Hold & Wait {edges from a process to a resource} holds one resource while waiting for another Circular waiting P i P k allocation T i waits for T i+1 and holds a resource request edge edge requested by T i-1 sufficient only if one instance of each resource R j � 6 � 7 6 7-1

  6. Necessary Conditions Necessary Conditions for Deadlock for Deadlock Deadlock possible only if all four hold Deadlock possible only if all four hold Bounded resources Bounded resources P 0 A finite number of threads can use a A finite number of threads can use a resource; resources are finite resource; resources are finite No preemption No preemption Resource type Resource type the resource is mine, MINE! (until I with 5 instances the resource is mine, MINE! (until I with 5 instances P 4 P 1 release it) release it) Hold & Wait Hold & Wait holds one resource while waiting for holds one resource while waiting for another another Circular waiting Circular waiting T i waits for T i+1 and holds a resource T i waits for T i+1 and holds a resource requested by T i-1 requested by T i-1 P 3 P 2 sufficient only if one instance of each sufficient only if one instance of each resource resource � 7 � 7 7-2 7-3 Necessary Conditions Necessary Conditions for Deadlock for Deadlock Deadlock possible only if all four hold Deadlock possible only if all four hold Bounded resources Bounded resources P 0 P 0 A finite number of threads can use a A finite number of threads can use a owned owned resource; resources are finite resource; resources are finite by by No preemption No preemption Resource type Resource type the resource is mine, MINE! (until I with 5 instances the resource is mine, MINE! (until I with 5 instances P 4 P 1 P 4 P 1 release it) release it) Hold & Wait Hold & Wait holds one resource while waiting for holds one resource while waiting for another another Circular waiting Circular waiting T i waits for T i+1 and holds a resource T i waits for T i+1 and holds a resource requested by T i-1 requested by T i-1 P 3 P 2 P 3 P 2 sufficient only if one instance of each sufficient only if one instance of each resource resource � 7 � 7 7-4 7-5

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend