170 likes | 386 Views
Operating Systems CMPSC 473. Mutual Exclusion Lecture 14: October 14, 2010 Instructor: Bhuvan Urgaonkar. Mid-semester feedback. On Angel, format similar to SRTEs Please submit by end of the week Based on feedback so far: will do a revision of mutual exclusion related topics. Agenda.
E N D
Operating SystemsCMPSC 473 Mutual Exclusion Lecture 14: October 14, 2010 Instructor: Bhuvan Urgaonkar
Mid-semester feedback • On Angel, format similar to SRTEs • Please submit by end of the week • Based on feedback so far: will do a revision of mutual exclusion related topics
Agenda • Some classic synchronization problems using semaphores • Last class • Producer/Consumer problem • Readers/Writers problem • Solution was free of deadlocks • Starvation problem • Today • Readers/Writers problem • Consider more carefully the definition of starvation • Dining Philosophers problem
Readers-Writers Problem A data set shared among a number of concurrent processes Readers – only read the data set; they do not perform any updates Writers – can both read and write Problem – allow multiple readers to read at the same time. Only one writer may access the shared data at a given time Shared Data Data set Semaphore mutex initialized to 1 Semaphore wrt initialized to 1 Integer readcount initialized to 0
Readers-Writers Problem (Cont.) The structure of a writer process do { wait (wrt) ; // writing is performed signal (wrt) ; } while (TRUE); • mutex = 1 • wrt = 1 • readcount = 0 Allow only one writer at a time to write
Readers-Writers Problem (Cont.) The structure of a reader process do { wait (mutex) ; readcount ++ ; if (readcount == 1) wait (wrt) ; signal (mutex) ; // reading wait (mutex) ; readcount - - ; if (readcount == 0) signal (wrt) ; signal (mutex) ; } while (TRUE); • mutex = 1 • wrt = 1 • readcount = 0 Proceed only if no writer is writing; disallow writers once we proceed Signal a writer only when there are no more active readers
Readers/Writers • Note that starvation is said to occur only when a process, despite getting CPU, does not get to make use of it • Only writers are starved, not readers • Can we eliminate starvation for writers?
Dining-Philosophers Problem Shared data Bowl of rice (data set) Semaphore chopstick [5] initialized to 1
Dining-Philosophers Problem (Cont.) The structure of Philosopher i: do { wait ( chopstick[i] ); wait ( chopStick[ (i + 1) % 5] ); // eat signal ( chopstick[i] ); signal (chopstick[ (i + 1) % 5] ); // think } while (TRUE); • Deadlock? Starvation? • What happens if all pick their left chopsticks?
Dining-Philosophers Problem (Cont.) • Idea #1: Make the two wait operations occur together as an atomic unit (and the two signal operations) • Use another binary semaphore for this • Any problems with this?
Dining-Philosophers Problem (Cont.) • Idea #2: Does it help if one of the neighbors picks their left chopstick first and the other picks their right chopstick first? • What is the most # phils. that can eat simultaneously?
Bounded Buffer/Producer Consumer • Buffer has max capacity N • Producer can only add if buffer has room (i.e., count < N) • Consumer can only remove if buffer has item (i.e., count > 0) N = 4 Producer Consumer 2 empty slots 2 occupied slots
Producer Consumer: Mutex Locks mutex_lock m; int count = 0; Produce() { while (count == N); mutex_lock (m); … ADD TO BUFFER, count++ … mutex_unlock (m); } Consume() { while (count ==0); mutex_lock (m); … REMOVE FROM BUFFER, count-- … mutex_unlock (m); } • Downside: Busy waiting • Liveness guarantee depends on how lock is implemented • E.g., • Peterson’s => Mutex and bounded wait • Test&set => Only mutex
Binary Semaphores == Mutex Locks semaphore m = 1; int count = 0; Produce() { while (count == N); wait (m); … ADD TO BUFFER, count++ … signal (m); } Consume() { while (count ==0); wait (m); … REMOVE FROM BUFFER, count-- … signal (m); }
Producer Consumer: Semaphores semaphore sem = 1; semaphore full = 0; semaphore empty = N; Produce() { wait (empty); wait (sem); … ADD TO BUFFER, count++ … signal (sem); signal (full); } Consume() { wait (full); wait (sem); … REMOVE FROM BUFFER, count-- … signal (sem); signal (empty); } • Use three semaphores • Note important difference from condition variables • Signals are not lost • sem protects critical sections • full forces a consumer to wait till there is at least one item in buffer • empty ensures at most N items are produced between empty buffer and execution of a consumer
Producer Consumer: Semaphores semaphore sem = 1; int count = 0; Produce() { if (count == N) wait (sem); … ADD TO BUFFER, count++ … signal (sem); } Consume() { if (count == 0) wait (sem); … REMOVE FROM BUFFER, count-- … signal (sem); } • A non-working example • Identify the race condition here • That is, can a producer and consumer be in their critical sections simultaneously?
Producer Consumer: Semaphores semaphore sem = 1; int count = 0; mutex_lock m; Produce() { mutex_lock (m); if (count == N) wait (sem); … ADD TO BUFFER, count++ … signal (sem); mutex_unlock (m); } Consume() { mutex_lock (m); if (count == 0) wait (sem); … REMOVE FROM BUFFER, count-- … signal (sem); mutex_unlock (m); } • A non-working example • What happens if a consumer acquires the lock before an item is added to the buffer? • Deadlock!