Outline �� 0024 Spring 2010 � –9 :: 2 – �
Reasoning about parallel programs � 0024 Spring 2010 � –9 :: 3 – �
Reasoning about parallel programs � 0024 Spring 2010 � –9 :: 4 – �
Example � 0024 Spring 2010 � –9 :: 5 – �
Example, continued � 0024 Spring 2010 � –9 :: 6 – �
Updates � 0024 Spring 2010 � –9 :: 7 – �
Updates � 0024 Spring 2010 � –9 :: 8 – �
Slightly modi fi ed example � 0024 Spring 2010 � –9 :: 9 – �
Slightly different updates � 0024 Spring 2010 � –9 :: 10 – �
Example, another variation � 0024 Spring 2010 � –9 :: 11 – �
Slightly different updates � 0024 Spring 2010 � –9 :: 12 – �
Visibility of updates � 0024 Spring 2010 � –9 :: 13 – �
Recall � 0024 Spring 2010 � –9 :: 14 – �
Reasoning about programs � 0024 Spring 2010 � –9 :: 15 – �
Correctness � 0024 Spring 2010 � –9 :: 16 – �
(Absence of) deadlock � 0024 Spring 2010 � –9 :: 17 – �
Deadlock � 0024 Spring 2010 � –9 :: 18 – �
Liveness � 0024 Spring 2010 � –9 :: 19 – �
Fairness models � 0024 Spring 2010 � –9 :: 20 – �
Strong and weak fairness � Here � s the classical example to see the difference: � � � Assume fl ag==1 if and only if (“iff”) a thread wants to request service. � � � Thread A periodically issues a request, then cancels � � � Thread B continuously issues a request � � � Service provide checks at times t0, t1, t2 � 1 � A: � 0 � 1 � B: � 0 � t0 � t1 � t2 � 0024 Spring 2010 � –9 :: 21 – �
Synchronization � Foundation: mutual exclusion � � � Sequence of operations to be executed atomically called critical section � � � Mutual exclusion: instructions from critical sections must not be interleaved � Model of a program � � loop { � non_critical_section � � enter_protocol � � critical section � exit_protocol � non_critical_section � 0024 Spring 2010 � –9 :: 22 – � } �
Requirements for mutex solution � No deadlock. � � � If some threads attempt to execute their critical section, then one of them must eventually succeed. � No starvation. � � � If a thread wants to enter its critical section, eventually it will succeed. � No undue delays. � � � If there is no contention, a thread that wishes to enter its critical section will succeed. � � � Corrollary: overhead should be small in the absence of contention. � 0024 Spring 2010 � –9 :: 23 – �
Notes � Thread not allowed to halt in critical section � � � Halt in non_critical_section not allowed to interfere with the rest of the system � 0024 Spring 2010 � –9 :: 24 – �
First attempt � Idea: volatile int variable that indicates which thread can proceed. � Volatile assures that all threads see updates to these variables in order, i.e. if this sequence of updates is done (a, b, c volatile and initially 0) � � a = 1; � b = 2; � c = 3; � � then a thread that sees that c==3 will also see that a==1 and b==2. No guarantee on when a thread sees the updates, though. � 0024 Spring 2010 � –9 :: 25 – �
First attempt: PingPong � class PingPong { public static void main(String[] args) { Turn t = new Turn(); Thread t1 = new Thread(new Worker(0,t)); Thread t2 = new Thread(new Worker(1,t)); t1.start(); t2.start(); } 0024 Spring 2010 � –9 :: 26 – � }
class Turn { volatile int turn = 0; } class Worker implements Runnable { private int myid; private Turn signal; Worker(int id, Turn t) { myid = id; signal = t; } public void run() { while (true) { while ( !(signal.turn == myid) ) { } signal.turn = (myid==0) ? 1 : 0; } } 0024 Spring 2010 � –9 :: 27 – � }
In detail � public void run() { while (true) { S1: non_critical section S2: while ( !(signal.turn == myid)){} S3: critical_section S4: signal.turn = (myid==0) ? 1 : 0; } } 0024 Spring 2010 � –9 :: 28 – �
Observations � Solution satis fi es the mutual exclusion requirement. � � � Reasoning: Suppose both threads are in their critical section (S3) � � � Assume that Thread A [id 0] entered fi rst (time t1), Thread B [id 1] at time t2 = t1 + d, and A remained in its critical section during d. � � � At time t1, turn == 0, so A could exit from the loop S2. � � � At time t2, turn == 1, so B could exit from the loop S2. � � � But during d, A remained in the critical section, so no assignment to turn, and turn == 0. � � � So turn == 1 at time t2: � � � Contradiction. � 0024 Spring 2010 � –9 :: 29 – �
Solution cannot deadlock. � There is no starvation. � Solution can fail in the absence of contention. � 0024 Spring 2010 � –9 :: 30 – �
Log � java PingPong � 0.... leaving � 0 before loop � 1 past loop ... � 0 past loop ... � 1 before loop � 0 before loop � 0.... leaving � 1.... leaving � 0 before loop � 0 past loop ... � 1 past loop ... � 1 before loop � 1.... leaving � 0 past loop ... � 0.... leaving � 1 before loop � 1 past loop ... � 0.... leaving � 0 before loop � 0 before loop � 1 past loop ... � 1.... leaving � 1 before loop � 0 past loop ... � 0024 Spring 2010 � –9 :: 31 – �
Second attempt � Each thread has its own variable ( fl ag) � � � Request0 == 0 indicates that thread w/ id 0 wants to enter its critical section � � � Request0 == 1 indicates that thread w/ id 0 does not want to enter. � � � Request1 == 0 … � 0024 Spring 2010 � –9 :: 32 – �
class Turn { // 0 : wants to enter exclusive section // 1 : does not want to enter ... volatile int request0 = 1; volatile int request1 = 1; } 0024 Spring 2010 � –9 :: 33 – �
Worker 0 � class Worker0 implements Runnable { private int myid; private Turn signal; Worker0(Turn t) { myid = 0; signal = t; } public void run() { // next slide } } 0024 Spring 2010 � –9 :: 34 – �
Worker 0 � while (true) { while (true) { if (signal.request1 == 1) break; } signal.request0 = 0; // critical section signal.request0 = 1; } 0024 Spring 2010 � –9 :: 35 – �
Worker 1 � public void run() { while (true) { while (true) { if (signal.request0 == 1) break; } signal.request1 = 0; // critical section signal.request1 = 1; } } 0024 Spring 2010 � –9 :: 36 – �
Discussion � Two threads A [id 0] and B [id 1] can be in their critical sections at the same time. � Possible interleaving � � A checks request1, request1 == 1 � B checks request0, request0 == 1 � � A sets request0 = 0 � � B sets request1 = 0 � � A enters critical section � � B enters critical section � 0024 Spring 2010 � –9 :: 37 – �
Log � 0 before loop � 0 enter ... � 1 before loop � 0.... exit � 0 before loop � 1 enter ... � 0 enter ... � 1.... exit � 0024 Spring 2010 � –9 :: 38 – �
Third attempt � Can � t stop a thread after loop � request1 (request0) set too late - must be part of the enter protocol � 0024 Spring 2010 � –9 :: 39 – �
Third attempt � class Turn { // 0 : wants to enter exclusive section // 1 : does not want to enter ... private volatile int flag = 1; void request() { flag = 0;} void free() { flag = 1; } int read() { return flag; } } 0024 Spring 2010 � –9 :: 40 – �
Worker � class Worker implements Runnable { private int myid; private Turn mysignal; private Turn othersignal; Worker(int id, Turn t0, Turn t1) { myid = id; mysignal = t0; othersignal = t1; } 0024 Spring 2010 � –9 :: 41 – �
Worker � public void run() { while (true) { mysignal.request(); while (true) { if (othersignal.read() == 1) break; } // critical section mysignal.free(); } } 0024 Spring 2010 � –9 :: 42 – � }
Master � class Synch3b { public static void main(String[] args) { Turn gate0 = new Turn(); Turn gate1 = new Turn(); 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 � –9 :: 43 – �
Worker � public void run() { while (true) { mysignal.request(); while (true) { if (othersignal.read() == 1) break; } // critical section mysignal.free(); } } 0024 Spring 2010 � –9 :: 44 – � }
Worker 0 � public void run() { while (true) { A1: A2: s0.request(); A3: while (true) { if (s1.read() == 1) break; } A4: // critical section A5: s0.free(); } } 0024 Spring 2010 � –9 :: 45 – � }
Worker 1 � public void run() { while (true) { B1: B2: s1.request(); B3: while (true) { if (s0.read() == 1) break; } B4: // critical section B5: s1.free(); } } 0024 Spring 2010 � –9 :: 46 – � }
Recommend
More recommend