Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS444/CS544 Operating Systems Classic Synchronization Problems 2/26/2007 Prof. Searleman

Similar presentations


Presentation on theme: "CS444/CS544 Operating Systems Classic Synchronization Problems 2/26/2007 Prof. Searleman"— Presentation transcript:

1 CS444/CS544 Operating Systems Classic Synchronization Problems 2/26/2007 Prof. Searleman jets@clarkson.edu

2 Outline Monitors & Semaphores Classic Synchronization Problems Bounded Buffer NOTE: Read: Chapter 7 HW#7 posted: due Wed. 3/07/07 HW#7 Exam#1 returned – will discuss on Friday

3 Classical Synchronization Problems Bounded-Buffer Problem (also called Producer-Consumer) one-way communication with limited resources Dining-Philosophers Problem shared resources Readers and Writers Problem shared database

4 Recap: Waiting Inside a Monitor condition variable used to wait for a particular event or situation 2 operations: wait() & signal() The operation x.wait() means that the process invoking this operation is suspended until another process invokes x.signal(); The operation wait allows another process to enter the monitor (or no one could ever call signal!) The x.signal operation resumes exactly one suspended process. If no process is suspended, then the signal operation has no effect

5 Monitor Invariants Can specify invariants that should hold whenever no thread is in the monitor Not checked by compiler More like a precondition to be respected by the programmer Right back into the problem with not having compiler support for mutual exclusion except in very simple cases!

6 Who first? If thread in Monitor calls x.signal waking another thread then who is running in the monitor now? (Can’t both be running in the monitor!) Hoare semantics Run awakened thread next; signaler blocks Mesa semantics Waiter is made ready; signaler continues

7 Does it matter? Yes If waiter runs immediately, then clearly “condition” being signaled still holds Signaler must restore any “monitor invariants” before signaling If waiter runs later, then when waiter finally enters monitor must recheck condition before executing Signaler need not restore any “monitor invariants” before signaling upon exiting

8 Write different code as a result If waiter runs immediately then if (condition not true) C.wait() If waiter runs later then while (condition not true) C.wait() Conclusion? Mesa style (waiter runs later) has fewer context switches and directly supports a broadcast primitive (i.e. c.signalAll) While instead of if not a big price to pay

9 Classical Synchronization Problems Bounded-Buffer Problem (aka Producer-Consumer) one-way communication with limited resources Dining-Philosophers Problem shared resources Readers and Writers Problem shared database

10 Bounded Buffer Producer/Consumer Finite size buffer (array) in memory shared by multiple processes/threads Producer threads “produce” an item and place it in the buffer Consumer threads remove an item from the buffer and “consume” it Why do we need synchronization? Shared data = the buffer state Which parts of buffer are free? Which filled? What can go wrong? Producer doesn’t stop when no free spaces; Consumer tries to consume an empty space; Consumer tries to consume a space that is only half-filled by the producer; Two producers try to produce into same space; Two consumers try to consume the same space,…

11 Producer thread Reason(s) to wait? How to implement? Consumer thread Reason(s) to wait? How to implement? CONCEPT: Producers produce items to be stored in the buffer. Consumers remove and consume items which have been stored. Mutual exclusion must be enforced on the buffer itself. Moreover, producers can store only when there is an empty slot, and consumers can remove only when there is a full slot.

12 Monitor Solution to Producer/Consumer The buffer and its control variables are encapsulated by a monitor. The monitor provides procedures to put an item in the buffer and to take an item out of the buffer. The monitor includes two condition variables: slot_free represents the condition that there is space for an item, and item_present represents the condition that at least one item is present in the buffer. In this example, the buffer is implemented as an array of size MAX treated as a circular (ring) buffer. Variables in and out give the index of the next position for putting in and taking out (if any). Variable count gives the number of items in the buffer.

13 Structure of a Monitor monitor BB { // shared variables condition slot_free, item_present; anytype buffer[MAX]; int in, out, count; // monitor procedures void put_in_buffer(anytype item); anytype get_from_buffer(void); // initialization code for shared variables in = 0; out = 0; count = 0; } // end monitor BB

14 Producer & Consumer threads: PRODUCER : repeat { /* produce an item */ item = produce(); /* put it in the buffer */ BB.put_in_buffer(item); } until done; CONSUMER: repeat { /* get item from the buffer */ item = BB. get_from_buffer(); /* consume it */ consume(item); } until done;

15 void put_in_buffer(anytype item) { /* if no space is available, wait for one */ if (count >= MAX) slot_free.wait(); /* store the item */ buffer[in] = item; in = in + 1 mod n; count = count + 1; /* signal that the item is present */ item_present.signal(); } anytype get_from_buffer(void){ anytype item; /* if no items are present, wait for one */ if (count <= 0) item_present.wait(); /* get the next item */ item = buffer[out]; out = out + 1 mod n; count = count - 1; /* announce that a space is free */ slot_free.signal(); /* return the item */ return(item); }

16 Semaphore Solution to Bounded-Buffer semaphore_t mutex; semaphore_t full; semaphore_t empty; container_t { BOOL free = TRUE; item_t item; } container_t buffer[FIXED_SIZE]; void initBoundedBuffer{ mutex.value = 1; full.value = 0; empty.value = FIXED_SIZE }

17 Semaphore Solution to Bounded-Buffer void producer (){ container_t *which; wait(empty); wait(mutex); which = findFreeBuffer(); which->free = FALSE; which->item = produceItem(); signal(mutex); signal(full); } void consumer (){ container_t *which; wait(full); wait(mutex); which = findFullBuffer(); consumeItem(which->item); which->free = TRUE; signal(mutex); signal(empty); } Can we do better? Lock held while produce/consume? Exercise


Download ppt "CS444/CS544 Operating Systems Classic Synchronization Problems 2/26/2007 Prof. Searleman"

Similar presentations


Ads by Google