outline
play

Outline 0024 Spring 2010 10 :: 2 Recall 0024 Spring 2010 10 - PowerPoint PPT Presentation

Outline 0024 Spring 2010 10 :: 2 Recall 0024 Spring 2010 10 :: 3 0024 Spring 2010 10 :: 4 0024 Spring 2010 10 :: 5 Dekker: core classes class Insist { private


  1. Outline �� 0024 Spring 2010 � – 10 :: 2 – �

  2. Recall � 0024 Spring 2010 � – 10 :: 3 – �

  3. 0024 Spring 2010 � – 10 :: 4 – �

  4. 0024 Spring 2010 � – 10 :: 5 – �

  5. Dekker: core classes � class Insist { private volatile int winner; void setWinner(int id) { winner = id; } int getWinner() { return winner;} } class Turn { private volatile int flag = 1; private final Insist insist; Turn (Insist a) { insist = a; } // continued 0024 Spring 2010 � – 10 :: 6 – �

  6. Dekker: core classes , part 2 � void request() { flag = 0;} void free() { flag = 1; } int read() { return flag; } void setWinner(int id) { insist.setWinner(id); } int getWinner() { return insist.getWinner(); } } 0024 Spring 2010 � – 10 :: 7 – �

  7. public void run() { � Worker int nextid; if (myid==0) {nextid = 1;} else {nextid=0;}; while (true) { mysignal.request(); while (true) { if (othersignal.read() == 1) break; if (mysignal.getWinner() == nextid) { mysignal.free(); while (true) { if (mysignal.getWinner() == myid) break; }; // other thread won 1st round mysignal.request(); } 0024 Spring 2010 � – 10 :: 8 – � }

  8. Worker, continued � // critical section mysignal.free(); mysignal.setWinner(nextid); } // end loop } } 0024 Spring 2010 � – 10 :: 9 – �

  9. Master � class Dekker { public static void main(String[] args) { Insist arbiter = new Insist(); Turn gate0 = new Turn(arbiter); Turn gate1 = new Turn(arbiter); Thread t1 = new Thread(new Worker(0,gate0,gate1)); Thread t2 = new Thread(new Worker(1,gate1,gate0)); t1.start(); t2.start(); } 0024 Spring 2010 � – 10 :: 10 – � }

  10. Worker 0 � public void run() { while (true) { A1: s0.request(); while (true) { A2: if (s1.read() == 1) break; A3: if (s0.getWinner() == 1) { s0.free(); while (true) { if (s0.getWinner() == 0) break; }; // worker 1 won 1st round s0.request(); } // end check if worker 1 insists } A4: // critical section s0.free(); s0.setWinner(1); } // end loop 0024 Spring 2010 � – 10 :: 11 – � } // end run

  11. Worker 1 � public void run() { while (true) { s1.request(); while (true) { if (s0.read() == 1) break; if (s1.getWinner() == 0) { s1.free(); while (true) { if (s1.getWinner() == 1) break; }; // worker 0 won 1st round s1.request(); } // end check if worker 0 insists } // critical section s1.free(); s1.setWinner(0); } // end loop 0024 Spring 2010 � – 10 :: 12 – � } // end run

  12. Can both threads enter the critical section? � 0024 Spring 2010 � – 10 :: 13 – �

  13. 0024 Spring 2010 � – 10 :: 14 – �

  14. Temporal logic � We want to show that there is no starvation. � Must reason that an event (start of critical section) will happen eventually. � E.g., for worker 0 we must show that once A1 is executed eventually A4 is reached � � Must show the same for Thread B … � 0024 Spring 2010 � – 10 :: 15 – �

  15. Worker 0 � public void run() { while (true) { A1: s0.request(); while (true) { A2: if (s1.read() == 1) break; A3: if (s0.getWinner() == 1) { s0.free(); while (true) { if (s0.getWinner() == 0) break; }; // worker 1 won 1st round s0.request(); } // end check if worker 1 insists } A4: // critical section s0.free(); s0.setWinner(1); } // end loop 0024 Spring 2010 � – 10 :: 16 – � } // end run

  16. Notation � � p means “p is always true” � � p means “p is eventually true” � Shorthand to save us typing � 0024 Spring 2010 � – 10 :: 17 – �

  17. Notation � � p means “p is always true” � � � After p turns true we read the value “true” whenever we want to � � q means “q is eventually true” � � � No statement how long q will remain true. � Often we must show � � p � � � Eventually p turns true and will remain true as long as we care to check it � Example: � � � � � p , � � q ⇒ � �� ( p � � q ) � 0024 Spring 2010 � – 10 :: 18 – �

  18. Absence of starvation � 0024 Spring 2010 � – 10 :: 19 – �

  19. Lemma 1 � 0024 Spring 2010 � – 10 :: 20 – �

  20. 0024 Spring 2010 � – 10 :: 21 – �

  21. Lemma 2 � 0024 Spring 2010 � – 10 :: 22 – �

  22. Proof of freedom from starvation � 0024 Spring 2010 � – 10 :: 23 – �

  23. Proof, continued � 0024 Spring 2010 � – 10 :: 24 – �

  24. Proof, continued � 0024 Spring 2010 � – 10 :: 25 – �

  25. Semaphores � Programming with critical sections is hard (impossible). � Better abstractions are needed. � � � We have seen the event queues in Java � � � We now look at another primitive � � � More comfortable than critical sections based on Dekker � s solution yet still not too complicated � Idea: a semaphore S is an integer-valued variable with two operations � � � P(S): if S>0 then S:= S-1 � else suspend thread � � � V(S): if (there are suspended threads) then wake one of them � else S = S+1 � 0024 Spring 2010 � – 10 :: 26 – �

  26. Semaphores - operations � P: wait, V: signal � P(S) and V(S) are atomic � � � No interruption � S must be given a non-negative starting value (S 0 ) � V(S) wakes up one thread -- no way to specify which one � Binary semaphores: S is intitalized with 1 � � � Legal values are 0 and 1 � 0024 Spring 2010 � – 10 :: 27 – �

  27. Semaphore invariants � i) � S � 0 � ii) � S = S 0 + #V(S) - #P(S) � 0024 Spring 2010 � – 10 :: 28 – �

  28. Semaphore use � It � s easy to make programming mistakes: forget a V(S) and no other thread will be able to make progress � � � Other threads remain suspended on S forever � Model of a program � loop { � � non_critical_section � � P(S) � � critical section � V(S) � } � 0024 Spring 2010 � – 10 :: 29 – �

  29. Properties � Mutual exclusion � � � Let S be a binary semaphore (i.e. S 0 = 1) � � � Proof: Let #T be the number of threads in their critical sections. Show that (#T + S == 1) is invariant. � � � Since S � 0 it follows that #T � 1. � � � Show that (#T + S == 1) is invariant: � � � #T == #P(S) - #V(S) � � � S == 1 + #V(S) - #P(S) � � � S == 1 - #T � � � #T + S == 1 � Absence of deadlock � Absence of starvation of a thread � 0024 Spring 2010 � – 10 :: 30 – �

  30. N threads � Solution with semaphores works for N threads � � � Our proof did not rely on the number of threads � Recall our different kinds of fairness - corresponding classes of semaphores � 0024 Spring 2010 � – 10 :: 31 – �

  31. Semaphores � Blocked-set semaphore: (Model used so far) V(S) wakes up one of the suspended threads � Blocked-queue semaphore: Suspended threads are kept in a FIFO queue, wake up in order of suspension � � � P(S): if (S >0) S-- else {append to tail of queue} � � � V(S): if ( ∃ suspended threads) {wake up thread at head of queue, remove it from queue} else S++ � Busy-wait semaphore: Value of S tested in busy wait loop (the if-stmt executes atomically but different threads may execute their if-stmt in interleaved manner) � � � � P(S): while (true) { � � � � if (S>0) { S=S-1; break;} } � � � V(S): S++ � 0024 Spring 2010 � – 10 :: 32 – �

  32. Properties � For a busy-wait semaphore, starvation is possible. � 0024 Spring 2010 � – 10 :: 33 – �

  33. “Dining Philosophers” � N philosophers (e.g., N==5) � N (5) study rooms � 1 dining room � 1 dining table with N (5) bowls and N (5) forks � � � Bowls and forks remain on table � Simple life of a philosopher: � while (true) { � // think � // eat � } � 0024 Spring 2010 � – 10 :: 34 – �

  34. Rules � A philosopher eats only if s/he has two forks � � � Needs those to heap pasta into the bowl � � � Once a philosopher has a fork, s/he hangs on to it until s/he can eat � No two philosophers may hold the same fork simultaneously � Your task: organize the life of the philosophers � No deadlock � No individual starvation � Efficient behavior (access to food) in the absence of contention � 0024 Spring 2010 � – 10 :: 35 – �

  35. Dining table � 0024 Spring 2010 � – 10 :: 36 – �

  36. Idea � 0024 Spring 2010 � – 10 :: 37 – �

  37. Semaphore solution 1 Semaphore [] fork = new Semaphore[5]; // Default semaphore is binary // Philosopher I (0 � I � 4) while (true) { // think fork[i].p(); // right fork fork[mod(i+1,5)].p(); // left fork // eat fork[i].v(); fork[mod(i+1,5)].v(); } 0024 Spring 2010 � – 10 :: 38 – �

  38. Problem: Deadlock � 0024 Spring 2010 � – 10 :: 39 – �

  39. Deadlock avoidance � Limit number of philosophers in dining room � � � � additional semaphore to control room occupancy � Semaphore [] fork = new Semaphore[4]; Semaphore room = new Semaphore(4); // init to 4 // Philosopher i: while (true) { // think room.p(); fork[i].p(); fork[mod(i+1,5)].p(); // eat fork[i].v(); fork[mod(i+1,5)].v(); room.v(); } 0024 Spring 2010 � – 10 :: 40 – �

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