970 likes | 1.12k Views
Christian Schulte cschulte@kth.se Software and Computer Systems School of Information and Communication Technology KTH – Royal Institute of Technology Stockholm, Sweden. Concurrency Runtime Finishing Erlang. ID1218 Lecture 06 2009-11-16. Overview. Concurrent MiniErlang
E N D
Christian Schulte cschulte@kth.se Software andComputer Systems School of Information and Communication Technology KTH – Royal Institute of Technology Stockholm, Sweden ConcurrencyRuntimeFinishing Erlang ID1218 Lecture 06 2009-11-16
Overview • Concurrent MiniErlang • sketch how it really computes • builds on MiniErlang • Analyzing runtime • asymptotic complexity, big-O notation • analyzing recursive functions • Wrapping up the Erlang part • will return later as point for comparison ID1218, Christian Schulte
Processes With State ID1218, Christian Schulte
Processes • Receive messages • To be useful they need to maintain state • changing over time • Model: process is modeled by function state message state ID1218, Christian Schulte
Process States messages receive a a a s1 s2 s0 … ID1218, Christian Schulte
Defining a Process With State • Process • how it reacts to messages • how it transforms the state • from which initial state it starts • Additionally • process might compute by sending messages to other processes ID1218, Christian Schulte
Example: Logic of a Cell Process cell({assign,New},S) -> New; cell({access,PID},S) -> PID ! {self(),S}, S. • Captures • how the process transforms state • how it acts to incoming messages ID1218, Christian Schulte
A Generic Process With State serve(F,InS) -> receive Msg -> OutS = F(Msg,InS), serve(F,OutS) end. cellserver() -> spawn(fun () -> serve(fun cell/2,0) end). • Can be started • with function that performs state transitions • initial value for state ID1218, Christian Schulte
Making The Server Smarter serve(F,InS) -> receive kill -> void; … Msg -> OutS = F(Msg,InS), serve(F,OutS) end. • Add generic functionality to server ID1218, Christian Schulte
A Reconfigurable Server • Behavior of server defined by • generic message receipt • specific state transformation plus communication • Idea: make server reconfigurable • change how state is transformed • adapt state to possibly new representation ID1218, Christian Schulte
A Reconfigurable Server serve(F,InS) -> receive kill -> void; {update,NewF,Adapt} -> serve(NewF,Adapt(InS)); … Msg -> OutS = F(Msg,InS), serve(F,OutS) end. ID1218, Christian Schulte
Buffered Cells bcell({assign,V},{_,B}) -> {V,B}; bcell({access,PID},{V,B}) -> PID ! {self(),V}, {V,B}; bcell({save},{V,_}) -> {V,V}; bcell({restore},{_,B}) -> {B,B}. • Features states {V,B} with value V and buffer B ID1218, Christian Schulte
Reconfiguring the Server > C=cellserver(). … > C ! {assign,4}. … > C ! {update, fun bcell/2, fun (Old) -> {Old,0} end}. … > C ! {save}. … ID1218, Christian Schulte
Coordination ID1218, Christian Schulte
Protocols • Protocol: rules for sending and receiving messages • programming with processes • Examples • broadcasting messages to group of processes • choosing a process • Important properties of protocols • safety • liveness ID1218, Christian Schulte
Choosing a Process • Example: choosing the best lift, connection, … • More general: seeking agreement • coordinate execution • General idea: • Master • send message to all slaves containing reply PID • select one slave: accept • all other slaves: reject • Slaves • answer by replying to master PID • wait for decision from master ID1218, Christian Schulte
Master: Blueprint decide(SPs) -> Rs=collect(SPs,propose), {SP,SPr}=choose(SPs,Rs), SP ! {self(),accept}, broadcast(SPr,reject}. • Generic: • collecting and broadcasting • Specific: • choose single process from processes based on replies Rs ID1218, Christian Schulte
Slave: Blueprint slave() -> receive {M,propose} -> R=…, M ! {self(),R}, receive {M,accept} -> …; {M,reject} -> … end end ID1218, Christian Schulte
Avoiding Deadlock • Master can only proceed, after all slaves answered • will not process any more messages until then • receiving messages in collect • Slave can only proceed, after master answered • will not process any more messages until then • What happens if multiple masters for same slaves? ID1218, Christian Schulte
Deadlock A M B C N D Master Slave ID1218, Christian Schulte
Deadlock A M B C N D Master Slave ID1218, Christian Schulte
Deadlock A M B C N D Master Slave ID1218, Christian Schulte
Deadlock A M blocks! B C N D Master Slave ID1218, Christian Schulte
Deadlock A M blocks! B blocks! C N D Master Slave ID1218, Christian Schulte
Deadlock A • M blocks A, waits for B • N blocks B, waits for A • Deadlock!!!! M blocks! B blocks! C N D Master Slave ID1218, Christian Schulte
Avoiding Deadlock • Force all masters to send in order: • First A, then B, then C, … • Guarantee: If A available, all others will be available • difficult: what if dynamic addition and removal of lists • does not work with low-latency collect • low-latency: messages can arrive in any order • high-latency: receipt imposes strict order • Use an adaptor • access to slaves through one single master • slaves send message to single master • problem: potential bottleneck ID1218, Christian Schulte
Adaptor A M B C N D Master Slave ID1218, Christian Schulte
Adaptor adaptor() -> receive {decide,Client,PIDs} -> decide(PIDs), Client ! self(), adaptor() end. % A is PID of adaptor process ndecide(A,PIDs) -> A ! {decide,self(),PIDs}, receive A -> void end. • Run single dedicated adaptor process • master blocks until decision process has terminated ID1218, Christian Schulte
Liveness Properties • Important property of concurrent programs liveness • An event/activity might fail to be live • other activities consume all CPU power • message box is flooded (denial of services) • activities have deadlocked • … • Difficult: all possible interactions with other processes must guarantee liveness • reasoning of all possible interactions ID1218, Christian Schulte
Summary • Protocols for coordinating processes • Can lead to deadlocks • Simple structure best • Important: liveness guarantees ID1218, Christian Schulte
Process State Reconsidered ID1218, Christian Schulte
Creating a Cell Process cell() -> spawn(fun cell/2,0). • Cell process • initialized with zero as state ID1218, Christian Schulte
A Simple Task inc(C) -> C ! {access,self()}, receive {C,N} -> C ! {assign,N+1} end. • Increment the cell’s content by one • get the old value • put the new value • Does this work? NO! NO! Why? ID1218, Christian Schulte
A Simple Task Screwed… C=cell(), P1=spawn(fun () inc(C) end), P2=spawn(fun () inc(C) end), … • We insist on result being 2! • sometimes: 2 • sometimes: 1 • Why? ID1218, Christian Schulte
Execution Sketch A: Good • Process 1 • C receives {access,P1} value got: 0 • Process 1 • C receives {assign,1} value put: 1 • Process 2 • C receives {access,P2} value got: 1 • Process 2 • C receives {assign,2} value put: 2 ID1218, Christian Schulte
Execution Sketch A: Bad • Process 1 • C receives {access,P1} value got: 0 • Process 2 • C receives {access,P2} value got: 0 • Process 1 • C receives {assign,1} value put: 1 • Process 2 • C receives {assign,1} value put: 1 ID1218, Christian Schulte
What Is Needed • We need to avoid that multiple access and assign operations get out of order • We need to combine access and assign into one operation • we can not guarantee that not interrupted • we can guarantee that state is consistent • we can guarantee that no other message is processed in between • operation is called atomic ID1218, Christian Schulte
Cell With Exchange cell({assign,New},S) -> New; cell({access,PID},S) -> PID ! {self(),S}, S; cell({exchange,PID},S) -> PID ! {self(),S}, receive {PID,NewS} -> NewS end. ID1218, Christian Schulte
Incrementing Rectified inc(C) -> C ! {exchange,self()}, receive {C,N} -> C ! {self(),N+1} end • Important aspect • no message will be received in between! ID1218, Christian Schulte
State and Concurrency • Difficult to guarantee that state is maintained consistently in a concurrent setting • Typically needed: atomic execution of several statements together • Processes guarantee atomic execution ID1218, Christian Schulte
Other Approaches • Atomic exchange • lowlevel • hardware: test-and-set • Locks: allow only one thread in a “critical section” • monitor: use a lock together with a process • generalizations to single writer/multiple reader ID1218, Christian Schulte
Locking Processes • Idea that is used most often in languages which rely on state • Before state can be manipulated: lock must be acquired • for example, one lock per object • If process has acquired lock: can perform operations • If process is done, lock is released ID1218, Christian Schulte
A Lockable Process outside(F,InS) -> receive {acquire,PID} -> PID ! {ok,self()}, inside(F,InS,PID) end. inside(F,InS,PID) -> receive {release,PID} -> outside(F,InS) {PID,Msg} -> inside(F,F(Msg,InS)); end. ID1218, Christian Schulte
Safety Properties • Maintain state of processes in consistent fashion • do not violate invariants • to not compute incorrect results • Guarantee safety by • atomic execution • exclusion of other processes ("mutual exclusion") ID1218, Christian Schulte
Concurrent MiniErlang (CME) ID1218, Christian Schulte
Processes in CME • Computation state is a collection of processes P1 P2 … Pn • every process must be reduced eventually (fairness) • no order among processes (set of processes) • A process is an extended MiniErlang machine Es ; Vs ; n ; Ms • expression stack Es • value stack Vs • process identifier (PID) n • mailbox Ms ID1218, Christian Schulte
CME: Values and Expressions • Values now also include PIDs V := int | [] | [V1|V2] | n • PIDs cannot not appear in expressions • Expressions E := … | self() | E1!E2 | spawn(F) | E1,E2 | receiveC1; …; Cnend • Instructions CONS, CALL, SEND ID1218, Christian Schulte
Sequential Composition E1,E2Es ; Vs ; n ; Ms Pr → E1E2Es ; Vs ; n ; Ms Pr • Decompose into individual statements • obey order of statements • To be read: pick fairly any process that matches this pattern ID1218, Christian Schulte
Self PID self()Es ; Vs ; n ; Ms Pr → Es ; nVs ; n ; Ms Pr • Pushes process' own PID on the value stack ID1218, Christian Schulte
Process Spawning spawn(F)Es ; Vs ; n ; Ms Pr → Es ; mVs ; n ; Ms F(); ; m ; Pr • Create new process with • expression stack that executes call to F • an empty value stack • a fresh (not used elsewhere) PID m • an empty mailbox ID1218, Christian Schulte