1 / 38

Concurrency

Concurrency. Concurrency. A process is a program executing on a virtual computer Processor speed and multiplexing of shared resources are ignored Order of thread execution is non-deterministic Multiprocessing

llowell
Download Presentation

Concurrency

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Concurrency

  2. Concurrency • A process is a program executing on a virtual computer • Processor speed and multiplexing of shared resources are ignored • Order of thread execution is non-deterministic • Multiprocessing • A system may contain multiple processors on which cooperating threads/processes can execute simultaneously • Multi-programming • Thread/process execution can be interleaved on a single processor because of time-slicing

  3. The Basic Issue • Operations are not atomic • An atomic operation is one that executes to completion or does not execute at all • An atomic operation has “an all or nothing” flavor: • Either it executes to completion, or • Does not execute at all, and • No one can see a partially-executed state

  4. Critical Sections • A critical section is: • Consecutive program instructions • all instruction executes atomically • A critical section implementation must allow only one thread to execute in the critical section at any given time • A good implementation • Allows maximum concurrency while preserving correctness

  5. Implementation • Permit access to shared variables only within a critical section • General program structure Entry section Wait if already locked “Lock” Critical section code Exit critical section “Unlock”

  6. Properties • Concurrent programs are specified using properties, which is a predicate that evaluated over a run of the concurrent program. • Thus, it has the value true or false in each run of the program. • We say that the property holds if it is true in each run. • A property: the value of x is always at least as large as the value of y, and x has the value of 0 at least once. • Not a property: the average number of processes waiting on a lock is less than 1.

  7. Safety and liveness • Any property is either • a safety property, • A liveness property, or • a conjunction of a safety and a liveness property.

  8. Safety • A safety property is of the form nothing bad happens (i.e., all states are safe). • Examples: • The number of processes in a critical section is always less than 2. • Let p be the sequence of produced values and c be the sequence of consumed values. c is always a prefix of p.

  9. Liveness • A liveness property is of the form something good happens(i.e., a state is eventually achieved). • Examples: • A process that wishes to enter the critical section eventually enters. • p grows without bound. For every value x in p, x is eventually in c.

  10. Safety and Liveness • Showing a safety property P holds: • find a safety property P’: P’ => P; • show that P’ initially holds; • show that each step of the program maintains P’. • Showing a liveness property holds is usually done by induction.

  11. Basic Properties • Finite progress axiom Each process takes a step infinitely often. • Atomic shared variables Consider {x = A} any concurrent read of x will return x = B; either A or B. {x = B} {x = 0} cobegin x = x + 1; || x = x - 1; coend {x ∈ {-1, 0 1} }

  12. Producer/Consumer • Let p be the sequence of produced values and c be the sequence of consumed values. • c is always a prefix of p. • For every value x in p, x is eventually in c. • Bounded buffer variant: • Always |p| − |c| ≤ max

  13. Producer Active proctype producer () { do :: (turn== P) -> printf(“Produce\n”) turn = C od }

  14. Consumer Active proctype consumer() { do :: (turn== C) -> printf(“\tConsumer\n”) turn = P od }

  15. Correctness Conditions • A correct solution to the critical section problem must satisfy: • Safety: • Nothing bad ever happens! • At most one thread may be executing in the critical section (mutual exclusion) • Liveness: • Eventually something good happens!! • If one of more threads are in their entry section, then eventually at least one of them enters the critical section. • Further requirement: • Bounded waiting: If a thread iis in entry section, then there is a bound on the number of times that other threads are allowed to enter the critical section before thread i’ s request is granted

  16. Step by Step • Initial value of turn is p • At least one producer will find the guard :: (turn== P) -> to be true • So, using UNIX: Spin prodcons.pml | more Produce Consume Produce Consume • Not using UNIX: Spin –u14 prodcons.pml Produce Consume Produce Consume ----------------- Depth-limit (-u14 steps) reached

  17. Extensing the Example • Instantiate more than 1 process Active [2] proctype producer() {…} • Now we may violate CS by have 2 procucers in the CS [::(turn== P) ->]

  18. Revised Producer Consumer Example mtype = { P,C,N}; mtype turn=P; pid who; inline request(x,y) { atomic(x=y; who=0} } Inline release(x,y) { atomic {x=y; who=0} }

  19. Main Code Active [2] proctype producer() { do :: request (turn, P, N) -> printf (“P%d\n”,_pid); assert (who== _pid); release (turn, C) od } Active [2] proctype consumer() { do :: request (turn, C, N) -> printf (“C%d\n”,_pid); assert (who== _pid); release (turn, P) od }

  20. Printout Spin prodcons2.pml P1 C2 P1 C3 P0 C3 P1 C3 … • There is some non determinism in the model, since both consumers share the same guard condition

  21. Further Simulation init{ assert (false) } spin false.pml spin: line 1 “false.pml“, Error: assertion violated • A simulation is not a proof! • To prove that, invoke SPIN in verification mode spin –a prodcons2.pml #generate a verifier cc –o pan pan.c #compile the verifier

  22. ./pan #perform the verification (Spin version 4.0.7 - - 1 August 2003) Full statespace search for: never claim - (none specified) assertion violations + acceptance cycles - (not selected) invalid end state + State-vector 28 bytes, depth reached 7, errors: 0 14 states, stored 3 states, matched 17 transitions (= stored + matched) 0 atomic steps

  23. Summary • State-space = very small • No errors • No assertion violations

  24. Dekker's mutex algorithm bool turn, flag[2]; byte cnt; active [2] proctype mutex() /* Dekker's 1965 algorithm */ { pid i, j; i = _pid; j = 1 - _pid; again: flag[i] = true; do :: flag[j] -> if :: turn == j -> flag[i] = false; !(turn == j); flag[i] = true :: else fi :: else -> break od; cnt++; assert(cnt == 1); cnt--; /* critical section */ turn = j; flag[i] = false; Goto again }

  25. Spin Verification spin -a mutex.pml cc -o pan pan.c ./pan (Spin Version 4.0.7 – 1 August 2003) + Partial Order Reduction Full statespace search for: never claim - (none specified) assertion violations + cycle checks - (disabled by -DSAFETY) invalid end states + State-vector 20 byte, depth reached 65, errors: 0 190 states, stored 173 states, matched 363 transitions (= stored+matched) 0 atomic steps hash conflicts: 0 (resolved) (max size 2^18 states)

  26. Faulty Mutual Exclusion Algorithm Byte cnt; Byte x,y,z; Active[2] proctype user() { byte me= -pid+1; Again: x=me; if :: (y==0)||y==me)->skip :: else->goto again fi;

  27. z=me; if :: (x==me)->skip :: else->goto again fi; y=me; if :: (z==me)->skip :: else->goto again fi; /* enter CS */ cnt++; assert(cnt==1); cnt--; goto again; }

  28. Spin’s Verdict spin – a mutex_flaw.pml cc -0 pan pan.c .pan pan: assertion violated (cnt==1) (at depth 53) pan: wrote mutex_flaw.pml.trail

  29. Bakery Algorithm proctype A() { do :: 1 -> turnA = 1; turnA = turnB + 1; (turnB == 0) || (turnA < turnB); mutex ++; mutex --; turnA = 0; od }

  30. Dekker’s solution to the two processmutual exclusion problem #define true 1 #define false 0 #define Aturn false #define Bturn true bool x, y, t; proctype A() { x = true; t = Bturn; (y == false||t == Aturn); /*critical section*/ x = false } proctype B() { y = true; t = Aturn; (x == false || t == Bturn); /* critical section */ y = false } init { run A(); run B() }

  31. Peterson's Mutual Exclusion bit active [2] ; bit last ; byte crit ; proctype threadMX (bit self) { do :: break :: active [self] = 1 ; last = self ; (last != self || ! active[1-self]) ; /* insufficient is: (last != self) ; */ crit ++ ; assert crit == 1 ; /* mutual exclusion */ crit -- ; active [self] = 0 ; od } init { run threadMX (0) ; run threadMX (1) ; }

  32. Message Passing Mtype = {ini, ack, dreg, data, shutup, quiet, dead}; Chan M = [1] of {mtype}: Chan W = [1] of {mtype};

  33. Active proctype Mproc() { W!ini; /*connection */ M?ack; /*handshake */ timeout-> /*wait */ if /*two options */ :: W!shutup /*start shutdown */ :: W!dreq /*or request data */ M?data /*receive data */ do :: W!data /*send data */ :: W!shutup; /*or shutdown */ break; od fi; M?shutup; /*shutdown handshake */ W!quiet; M?dead }

  34. Active proctype Wproc() { W?ini; /*wait for ini */ M!ack; /*acknowledge */ do /*3 options */ :: W?dreq -> /*data requested */ M!data /*send data */ :: W?data -> /*receive data */ skip /*no response */ :: W?shutup -> M!shutup; /*start shutdown */ break; od; W?quiet; M!dead }

  35. Spin –c protocol Proc 0 = Mproc Proc 1 = Wproc q\p 0 1 1 W!ini 1 - W?ini 2 - M!ack 2 M?ack Timeout 1 W!shutup 1 - W?shutup 2 - M! shutup 2 M?shutup 1 W!quiet 1 - W?quiet 2 - M!dead 2 M?dead …

  36. SPIN Output proctype A state 1 -> state 2 => x = 1 state 2 -> state 3 => t = 1 state 3 -> state 4 => ((y == 0) || (t == 0)) state 4 -> state 5 => x = 0 state 5 -> state 0 => -end proctype B state 1 -> state 2 => y = 1 state 2 -> state 3 => t = 0 state 3 -> state 4 => ((x == 0) || (t == 1)) state 4 -> state 5 => y = 0 state 5 -> state 0 => -end proctype init state 1 -> state 2 => (run A()) state 2 -> state 3 => (run B()) state 3 -> state 0 => -end-

  37. Reader-Writer #define invariant (nr == 0 || !busy) byte nr; bool busy; proctype reader(){ do :: atomic{ (!busy) -> nr=nr+1} /* reading */ nr=nr-1 od; } proctype writer (){ do ::atomic { (nr==0 && !busy) ->busy=1} /*writing*/ busy=0; od;

  38. #define invariant (nr == 0 || !busy) byte nr; bool busy; proctype reader(){ do :: atomic{ (!busy) -> nr=nr+1} /* reading */ nr=nr-1 od; } proctype writer (){ do ::atomic { (nr==0 && !busy) ->busy=1} /*writing*/ busy=0; od; init{ nr=0; busy=0; run reader(); run reader(); run writer(); run writer(); } if :: (! ((invariant))) -> goto accept_all :: (1) -> goto T0_init fi; accept_all: skip } Reader/Writer

More Related