too much pizza
play

Too Much Pizza Person A Person B 3:00 Look in fridge. Pizza! - PDF document

Too Much Pizza Person A Person B 3:00 Look in fridge. Pizza! 3:05 Leave for store. Look in fridge. Pizza! 3:10 Arrive at store. Leave for store. Operating System I 3:15 Buy pizza. Arrive at store. 3:20 Arrive home. Buy pizza. 3:25


  1. Too Much Pizza Person A Person B 3:00 Look in fridge. Pizza! 3:05 Leave for store. Look in fridge. Pizza! 3:10 Arrive at store. Leave for store. Operating System I 3:15 Buy pizza. Arrive at store. 3:20 Arrive home. Buy pizza. 3:25 Put away pizza. Arrive home. Process Synchronization 3:30 Put pizza away. Oh no! Producer Consumer Cooperating Processes ! Consider: print spooler ! Model for cooperating processes – Enter file name in spooler queue ! Producer “produces” and item that – Printer daemon checks queue and prints consumer “consumes” ! Bounded buffer (shared memory) A B free 9 item buffer[MAX]; /* queue */ ... ... int counter; /* num items */ letter hw1 lab1.c (empty) 6 7 8 9 ! “Race conditions” (ugh!) Producer Consumer item i; /* item produced */ item i; /* item consumed */ int in; /* put next item */ int out; /* take next item */ while (1) { while (1) { while (counter == 0) {/*no-op*/} produce an item while (counter == MAX){/*no-op*/} item = buffer[out]; buffer[in] = item; out = (out + 1) % MAX; in = (in + 1) % MAX; counter = counter - 1; counter = counter + 1; consume the item } } 1

  2. Trouble! Critical Section R1 = counter P: {R1 = 5} ! Mutual Exclusion P: R1 = R1 + 1 {R1 = 6} – Only one process inside critical region R2 = counter {R2 = 5} C: ! Progress C: R2 = R2 -1 {R2 = 4} – No process outside critical region may block other processes wanting in counter = R1 P: {counter = 6} ! Bounded Waiting C: counter = R2 {counter = 4} – No process should have to wait forever (starvation) ! Note, no assumptions about speed! Second Try First Try: Strict Alternation int flag[1]; /* boolean */ int turn; /* shared, i or j */ while(1) { while(1) { flag[i] = true; while (turn <> i) { /* no-op */} while (flag[j]) { /* no-op */} /* critical section */ /* critical section */ turn = j flag[i] = false; /* remainder section */ /* remainder section */ } } Third Try: Peterson’s Solution Multiple-Processes int flag[1]; /* boolean */ int turn; ! “Bakery Algorithm” while(1) { ! Common data structures flag[i] = true; boolean choosing[n]; turn = j; int num[n]; while (flag[j] && turn==j){ } ! Ordering of processes /* critical section */ – If same number, can decide “winner” flag[i] = false; /* remainder section */ } 2

  3. Multiple-Processes Synchronization Hardware choosing[i] = true; ! Test-and-Set: returns and modifies atomically num[i] = max(num[0],num[1] …)+1 choosing[i] = false; int Test_and_Set(int target) { for (j=0; j<n; j++) { int temp; while(choosing[j]) { } temp = target; while( num[j]!=0 && target = true; (num[j],j)<(num[i],i) ) {} return temp; } } /* critical section */ num[i] = 0; Synchronization Hardware Semaphores ! Does not require “busy waiting” while(1) { ! Semaphore S (shared, often initially =1) while (Test_and_Set(lock)) { } – integer variable /* critical section */ – accessed via two (indivisible) atomic operations lock = false; wait(S): S = S - 1 /* remainder section */ if S<0 then block(S) } signal(S): S = S + 1 if S<=0 then wakeup(S) Critical Section w/Semaphores Semaphore Implementation semaphore mutex; /* shared */ ! How do you make sure the signal and the wait operations are atomic? while(1) { wait(mutex); /* critical section */ signal(mutex); /* remainder section */ } 3

  4. Trouble! Semaphore Implementation signal(S) wait(S) /* cr */ /* cr */ ! Disable interrupts – Why is this not evil? wait(S) wait(S) – Multi-processors? ! Use correct software solution /* cr */ ! Use special hardware, i.e.- Test-and-Set Process A Process B wait(S) wait(Q) wait(Q) wait(S) … … Classical Synchronization Dining Philosophers Problems ! Bounded Buffer ! Phisolophers – Think ! Readers Writers – Sit ! Dining Philosophers – Eat – Think ! Need 2 chopsticks to eat Dining Philosophers Philosopher i: while (1) { /* think… */ Other Solutions? wait(chopstick[i]); wait(chopstick[i+1 % 5]); /* eat */ signal(chopstick[i]); signal(chopstick[i+1 % 5]); } 4

  5. Other Solutions Readers-Writers ! Allow at most N-1 to sit at a time ! Readers only read the content of object ! Allow to pick up chopsticks only if both are ! Writers read and write the object available ! Critical region: ! Asymmetric solution (odd L-R, even R-L) – No processes – One or more readers (no writers) – One writer (nothing else) ! Solutions favor Reader or Writer Readers-Writers Readers-Writers Shared: Reader: semaphore mutex, wrt; wait(mutex); int readcount; readcount = readcount + 1; if (readcount==1) wait(wrt); signal(mutex); Writer: wait(wrt) /* read stuff */ /* write stuff */ wait(mutex); signal(wrt); readcount = readcount - 1; if (readcount==0) signal(wrt); signal(mutex); “Critical Region” “Critical Region” ! High-level construct ! Deadlocks still possible: region X do S – Process A: Process A Process B X is shared variable region X do wait(x-mutex) ... region Y do S1; ... wait(y-mutex) S is sequence of statements ... wait(x-mutex) – Process B: ! Compiler says: wait(y-mutex) ... region Y do wait(x-mutex) region X do S2; S X signal(x-mutex) A “cycle” B Y 5

  6. Bounded Buffer Conditional Critical Regions Shared: ! High-level construct struct record { region X when B do S item pool[MAX]; X is shared variable int count, in, out; B is boolean expression (based on c.r.) }; S is sequence of statements struct record buffer; Bounded Buffer Producer Bounded Buffer Consumer region buffer when (count < MAX){ region buffer when (count > 0){ pool[in] = i; /* next item*/ nextc = pool[out]; in = in + 1; out = (out + 1) % n; count = count + 1; count = count - 1; } } Monitors Monitor Producer-Consumer ! High-level construct monitor ProducerConsumer { ! Collection of: condition full, empty; /* not semphores */ integer count; – variables – data structures /* function prototypes */ – functions void producer(); – Like C++ classs void consumer(); ! One process active inside void enter(item i); item remove(); ! “Condition” variable } – not counters like semaphores 6

  7. Monitor Producer-Consumer Monitor Producer-Consumer void producer() { void enter (item i) { item i; if (count == N) wait(full); while (1) { /* add item i */ /* produce item i */ count = count + 1; ProducerConsumer .enter(i); if (count == 1) then signal(empty); } } } item remove () { void consumer() { if (count == 0) then wait(empty); item i; /* remove item into i */ while (1) { count = count - 1; i = ProducerConsumer .remove(); if (count == N-1) then signal(full); /* consume item i */ return i; } } } Ex: Cond. Crit. Region w/Sem Other IPC Synchronization region X when B do S { wait(x-mutex); ! Sequencers if (!B) { ! Path Expressions x-count = x-count + 1; ! Serializers signal(x-mutex); ! ... wait(x-delay); ! All essentially equivalent in terms of /* wakeup loop */ semantics. Can build each other. x-count = x-count -1 } /* remainder */ Ex: Wakeup Loop Ex: Remainder while (!B) { S; x-temp = x-temp + 1; if (x-count > 0) { if (x-temp < x-count) x-temp = 0; signal(x-delay); signal(x-delay); else } else signal(x-mutex); signal(x-mutex); wait(x-delay); } 7

  8. Trouble? Message Passing ! Monitors and Regions attractive, but ... ! Communicate information from one process to another via primitives: – Not supported by C, C++, Pascal ... send(dest, &message) N semaphores easy to add ! Monitors, Semaphores, Regions ... receive(source, &message) – require shared memory ! Receiver can specify ANY – break on multiple CPU (w/own mem) ! Receiver can block (or not) – break distributed systems ! Message Passing! Producer-Consumer Consumer Mailbox void Producer() { while (TRUE) { /* produce item */ void Consumer { build_message(&m, item); for (i=0; i<N; i++) send(consumer, &m); send(producer, &m); /* N empties */ receive(consumer, &m); /* wait for ack */ while(1) { }} receive(producer, &m); void Consumer { extract_item(&m, &item); while(1) { send(producer, &m); /* ack */ receive(producer, &m); “Rendezvous” /* consume item */ extract_item(&m, &item); } send(producer, &m); /* ack */ } /* consume item */ }} New Troubles ! Scrambled messages ( checksum ) ! Lost messages ( acknowledgements ) ! Lost acknowledgements ( sequence no .) New Troubles with Messages? ! Process unreachable (down, terminates) ! Naming ! Authentication ! Performance (from copying, message building) 8

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