Presentation is loading. Please wait.

Presentation is loading. Please wait.

Process Synchronization: Conclusion COS 431. Event Counters Alternative producer/consumer solution No need for mutex semaphore Example events: Adding/removing.

Similar presentations

Presentation on theme: "Process Synchronization: Conclusion COS 431. Event Counters Alternative producer/consumer solution No need for mutex semaphore Example events: Adding/removing."— Presentation transcript:

1 Process Synchronization: Conclusion COS 431

2 Event Counters Alternative producer/consumer solution No need for mutex semaphore Example events: Adding/removing item Idea: count events Processes wait for some number of events Atomicity: requires kernel support

3 Event Counter Example typedef int event_counter; event_counter in = 0; event_counter out = 0; void producer() { int item, num_items = 0; while (TRUE) { item = produce(); num_items++; /* wait for num out >= (num produced - buffer size) -- that is, until there’s room in the buffer */ await(out,num_items - NUM_SLOTS); enter_item(item,buffer); advance(&in); /* tell consumer something has arrived */ } void consumer () { int item, num_items = 0; while (TRUE) { num_items++; /* wait till buffer holds more items than we’d like to consume */ await(in,num_items); item = remove_item(buffer); advance(&out); consume_item(item); }

4 var buffer: shared record... end; /* consumer */ region buffer when count < n do begin /* add to buffer */ end; /* consumer */ region buffer when count > 0 do begin /* take from buffer */ end; Problems:  Cheating  Bugs Solution: programming language support for critical region Region construct region var when cond do stmt; Programming Language Support

5 Monitors Monitor: programming language construct for process synch. Object-like semantics:  procedures and variables are inside of monitors Only one process can be active within a monitor at any given time

6 Example monitor COS431; integer students[0..MAX]; last := 0; procedure register(student); … end; procedure drop(student); … end;

7 Potential problem: suppose we have bounded buffer problem need mutex......but also need way for process to wait until buffer is not full/empty yet if do this inside of monitor (naively), then deadlock

8 Solution: Condition Variables Condition variables used for interprocess communication Process can’t proceed => wait on a condition => not “active” Allows another process to enter monitor When resource free, active process uses signal on condition variable Original process awakens

9 Monitor Condition Variables Possible problem:  both signaler and ex-sleeper active simultaneously! Solution:  make process that signaled exit immediately from the monitor Can we do this?? If several processes are waiting on a condition variable, pick one Problem with condition variables:  they aren’t counters  ==> can’t buffer “signals” like a semaphore does -- signals can be lost solution: use state variables for each process if P1 wants to signal P2, but P2 not waiting - don’t signal Can’t get deadlock with monitors -- sleep and wakeup done only within monitor, and only one active process allowed at a time What if other process forgets to signal?

10 Example of Monitors: Bounded Buffer monitor COS431; integer students[0..MAX]; condition full; last := 0; procedure register(student); if last = MAX then wait(full); last := last + 1; students[last] := student; end; procedure drop(student); remove(student,students); last := last - 1; signal(full); end; P1: COS431.register(“Paul”);...last now equals max... COS431.register(“Mary”); ==> blocks P2: COS431.drop(“Jim”);...P1 wakes up, finishes adding

11 Problem with Monitors Requires programming language support C, Pascal, C++, Java – don’t have this Concurrent Euclid does, but... Same problems for regions

12 Problems with Synchronization Mechanisms Semaphores:  low-level  cheating  don’t work without shared memory--e.g., when processes are on different machines Signals:  only boolean information can be passed  only on same machine  cheating Monitors:  need programming language support  what if don’t have that language, or need multiple languages?

13 Message Passing New abstraction/metaphor:  process sends a message... ...another receives it later Same or different machines System calls -- e.g.:  send(dest,&msg);  receive(dest,&msg);  Not what they’re called in Unix (mq_send, e.g.) Blocking:  blocking receives  blocking or non-blocking sends

14 Solving the Registrar Problem with Messages Registrar Server void main() { while (TRUE) { receive(source,&msg); parse(msg); if (full(class)) { send(source, “sorry”); } else { add(student,class); send(source, “okay”); } Client Program void add(student,class) { create_msg(&msg,student,class); send(registrar,&msg); receive(registrar,&msg); report_results(&msg); }

15 Producer/Consumer with Messages Producer void main() { while (TRUE) { produce(&item); receive(consumer,&msg); pack(item,&msg); send(consumer,&msg); } Consumer void main() { // use messages instead of buffer for (i = 0; i < MAX; i++) { send(producer,&msg); } while (TRUE) { receive(producer,&msg); item = extract_item(&msg); // send back “empty” send(producer,&msg); process_item(item); }

16 Producer/Consumer Receiving from Anyone lpr Program, Machine A void main(int ARGC, char *ARGV[]) { process_args(&filename); pack(&msg,filename); send(lpd, &msg); // wait for reply receive(lpd,&msg); } lpd Daemon, Machine B void main() { while (TRUE) { receive(&any,&msg); unpack(&msg,&filename); send(any,&msg); print_file(filename); }

17 Message Passing Messages -- usually buffered until needed in kernel Can implement such that sends block  rendezvous: synchronize two processes Problems when processes on different machines:  Lost messages acknowledge messages ack lost: timeout, retransmit receiver must be able to handle redundant, out-of-order msgs  Addressing same machines: PIDs unique different machines: hostname, PIDs may not be unique use PID + Internet address:

18 Equivalence of Primitives Can implement one kind of synchronization primitive with another E.g.: implement monitors with semaphores  Need mutex -- govern access to monitor  Need semaphore for each condition variable  Compiler help: insert proper system calls where enter/exit monitor Process 1 enter_monitor: Down(mutex); work (in monitor) work exit_monitor: Up(mutex); work (out of monitor) enter_monitor: Down(mutex); blocked wake up, work in monitor work (in monitor) exit_signal(cvar1): Up(cvar1); work (out of monitor) Process 2 work enter_monitor: Down(mutex) blocked wake up, enter monitor work (in monitor) wait(cvar1): Up(mutex),Down(cvar1) blocked wake up work (in monitor) exit_monitor: Up(mutex)

19 Semaphores Implemented via Messages E.g., for distributed process synchronization Need a synchronization process Down(s) { put specifier for Down, s in msg; send(syncProc,&msg); receive(syncProc,&msg); } Up(s) { put specifier for Up, s in msg; send(syncProc,&msg); receive(syncProc,&msg); } syncProc() { semaphore semArray[N]; receive(&any,&msg); parse into Up/Down, s; if (Up) { semArray[s].count++; if (processes waiting on s) { remove process p from queue; send(p,&msg); } send(&any,&msg); } else { semArray[s].count--; if (semaphore[s].count < 0) { put s on queue; /* implicit block - no msg */ } else { send(&any,msg); }

20 Classical Problems: Dining Philosophers Five philosophers Two states: eating or thinking Fork between each pair Each needs two forks to eat (spaghetti, say; or chopsticks rather than forks) Problem: assure no deadlocks, no starvation

21 Dining Philosophers: Simple “Solution” Use one semaphore per fork while (TRUE) { think(); Down(left_fork); Down(right_fork); eat(); Up(right_fork); Up(left_fork); } Problem? Can we check fork first? Can we use mutex semaphore?

22 Dining Philosophers: Solution Use state array (eating, thinking, hungry) Also semaphore per philosopher Philosopher’s semaphore set to 0 initially void main() { while (TRUE) { think(); take_forks(i); eat(); // eating put_forks(i); } take_forks(i) { Down(mutex); state[i] = HUNGRY; test(i); // forks free? Up(mutex); Down(semaphore[i]); } test(i) { if ((state[i] == HUNGRY) && (state[right(i)] != EATING) && (state[left(i)] != EATING)) { state[i] = EATING; Up(semaphore[i]); } put_forks(i) { Down(mutex); state[i] = THINKING; test(left(i)); test(right(i)); Up(mutex); }

23 Readers/Writers Often:  multiple readers  multiple writers  ex: databases, ATMs, etc. Any problem with:  multiple readers?  multiple writers?  readers & writers simultaneously? How to synchronize, so that:  readers and writers respect shared data and  maximum utilization of shared resource? Solution uses two semaphores, mutex and wrt

24 Readers/Writers: Solution? writer: Down(mutex); Down(wrt);...write... Up(wrt); Up(mutex); end; reader: Down(mutex); readers++; if (readers == 1) Down(wrt); Up(mutex); Down(mutex); readers--; if (readers == 0) Up(wrt); Up(mutex); end;

25 A Readers/Writers Solution void reader() { while (TRUE) { down(mutex); rc++; // reader count if (rc == 1) down(wrt); up(mutex); data... down(mutex); rc--; if (rc == 0) up(wrt); up(mutex);...use data... } void writer () { while (TRUE) {...produce data... down(wrt);...write data... up(wrt); }

Download ppt "Process Synchronization: Conclusion COS 431. Event Counters Alternative producer/consumer solution No need for mutex semaphore Example events: Adding/removing."

Similar presentations

Ads by Google