390 likes | 452 Views
Christian Schulte cschulte@kth.se Software and Computer Systems School of Information and Communication Technology KTH – Royal Institute of Technology Stockholm, Sweden. Iterative Computations Concurrency. ID1218 Lecture 04 2009-11-04. A Fourth Look. A Better Length?. l([]) -> 0;
E N D
Christian Schulte cschulte@kth.se Software and Computer Systems School of Information and Communication Technology KTH – Royal Institute of Technology Stockholm, Sweden Iterative ComputationsConcurrency ID1218 Lecture 04 2009-11-04
A Fourth Look ID1218, Christian Schulte
A Better Length? l([]) -> 0; l([_|Xr]) -> 1+l(Xr). l([],N) -> N; l([_|Xr],N) -> l(Xr,N+1). • Two different functions: l/1 and l/2 • Which one is better? ID1218, Christian Schulte
Running l/1 l([1,2,3]) ; → [1,2,3]CALL(l/1) ; → CALL(l/1) ;[1,2,3] → 1+l([2,3]); → 1l([2,3])ADD; → l([2,3])ADD;1 → [2,3]CALL(l/1)ADD;1 → CALL(l/1)ADD;[2,3]1 → 1+l([3])ADD;1 → 1l([3])ADDADD;1 → l([3])ADDADD;11 → … • requires stack space in the length of list ID1218, Christian Schulte
Running l/2 l([1,2,3],0) ; → [1,2,3]0 CALL(l/2) ; → 0 CALL(l/2) ;[1,2,3] → CALL(l/2) ;0[1,2,3] → l([2,3],0+1); → [2,3]0+1 CALL(l/2) ; → 0+1 CALL(l/2) ;[2,3] → 01ADDCALL(l/2) ;[2,3] → 1ADDCALL(l/2) ;0[2,3] → ADDCALL(l/2) ;10[2,3] → CALL(l/2) ;1[2,3] → l([3],1+1); → … • requires constant stack space! ID1218, Christian Schulte
Appending Two Lists app([],Ys) -> Ys; app([X|Xr],Ys) -> [X|app(Xr,Ys)]. • How much memory needed: easy! • Stack space… in the length of the first list • CONS accumulate on the stack ID1218, Christian Schulte
Iterative Computations • Iterative computations run with constant stack space • Make use of last optimization call • correspond to loops essentially • Tail recursive procedures are computed by iterative computations ID1218, Christian Schulte
Concurrency ID1218, Christian Schulte
The World Is Concurrent! • Concurrent programs several activities execute simultaneously (concurrently) • Most of the software you use is concurrent • operating system: IO, user interaction, many processes, … • web browser, Email client, Email server, … • telephony switches handling many calls • … ID1218, Christian Schulte
Why Should We Care? • Software must be concurrent… … for many application areas • Concurrency can be helpful for constructing programs • organize programs into independent parts • concurrency allows to make them independent with respect to how they execute • essential: how do concurrent programs interact? ID1218, Christian Schulte
Concurrent Programming Is Easy… • Erlang has been designed to be very good at concurrency… • Essential for concurrent programming here • message passing very simple interaction between concurrent programs • light-weight processes • no shared data structures independence ID1218, Christian Schulte
Concurrency in Erlang • Concurrent programs are composed of communicating processes • each process has a unique id: PID • processes are spawned to execute functions • send messages to PIDs • receive messages • messages are Erlang data structures • Erlang processes are not OS processes • one Erlang OS process can host lots of Erlang processes create by spawning • they are independent of the underlying OS ID1218, Christian Schulte
Creating Processes • Spawning a process: • takes a function as input • creates a new concurrently running process executing the function • returns the PID of the newly created process ID1218, Christian Schulte
Our First Process loop() -> receive kill -> io:format("Aargh: dead...~n"); Other -> io:format("Yummy: ~p~n",[Other]), loop() end. ID1218, Christian Schulte
Running the Process > P=spawn(fun loop/0). <0.62.0> > P ! apple. … Yummy: apple > P ! bogey. … Yummy: bogey > P ! kill. … Aaargh: dead > P ! ham. … ID1218, Christian Schulte
Processes Run Forever… • Why does process not run out of memory • property of loop/0 ID1218, Christian Schulte
Primitives • Creating processes • spawn(F) for function value F • spawn(M,F,As) for function F in module M with argument list As • Sending messages • PID ! message • Receiving messages • receive … end with clauses • Who am I? • self() returns the PID of the current process ID1218, Christian Schulte
Processes • Each process has a mailbox • incoming messages are stored in order of arrival • sending puts message in mailbox • Processes are executed fairly • if a process can receive a message or compute… …eventually, it will • It will pretty soon… • Simple priorities available (low) ID1218, Christian Schulte
Message Sending • Message sending P ! M is asynchronous • the sender does not wait until message has been processed • continues execution immediately • evaluates to M • When a process sends messages M1 and M2 to same PID, they arrive in order in mailbox • FIFO ordering • When a process sends messages M1 and M2 to different processes, order of arrival is undefined ID1218, Christian Schulte
Message Receipt • Only receive inspects mailbox • all messages are put into the mailbox • Messages are processed in order of arrival • that is, receive processes mailbox in order • If the receive statement has a matching clause for the first message • remove message and execute clause • always choose the first matching clause • Otherwise, continue with next message • Unmatched messages are kept in original order ID1218, Christian Schulte
Receive Example • receive c -> … end • receive d -> …; b -> … end • receive M -> … end d mailbox head a a a b b d c d d 1. 2. 3. ID1218, Christian Schulte
Receiving Multiple Messages seq() -> receive a -> receive b -> … end; c -> … end. • With other words: processes can use different receive statements • What does it mean • is a sent before b? • is a received before b? ID1218, Christian Schulte
Receive With Timeouts receive … after Time -> Expr end • If no matching message arrived within Time milliseconds, evaluate Expr • If only after clause present, process sleeps for Time milliseconds ID1218, Christian Schulte
Flushing the Mailbox flush() -> receive _ -> flush() after 0 -> true end. ID1218, Christian Schulte
Priority Receipt priority() -> receive alarm -> … after 0 -> receive M -> …, priority() end end. ID1218, Christian Schulte
Timed Repeater start(T,F) -> spawn(fun() -> rep(T,F) end). stop(PID) -> PID ! stop. rep(T,F) -> receive stop -> true after T -> F(), rep(T,F) end. ID1218, Christian Schulte
Different Message Types receive {a, … } -> … ; {b, … } -> … … end • Use tuples as messages • first field of tuple describes message type ID1218, Christian Schulte
Client Server Architectures ID1218, Christian Schulte
Client Server • Single server processing requests • wait for request • perform request • reply to request (ok or result) • Multiple clients sending requests • send request • wait for reply • Very common architecture • WWW, RPC, RMI, … • example: RPC ID1218, Christian Schulte
How to Reply: RPC • Server must know how to reply to client • client sends request… …plus its own PID • PID of process available via self() • After server has fulfilled request • sends back reply to sender's PID • RPC is synchronous • client must wait until reply received ID1218, Christian Schulte
RPC Server serve() -> receive {Client,Request} -> Response = process(Request), Client ! Response, serve() end. ID1218, Christian Schulte
RPC Client rpc(Server,Request) -> Server ! {self(), Request}, receive Response -> Response end. • This is easy… but wrong… • assumption: first message in mailbox is from server • but: can be from anybody! ID1218, Christian Schulte
Who Talks To Me? • If we only want to receive messages from process PID, messages must include PID • Sending P ! {self(), … } • Receipt PID= …, receive {P,…} when P==PID -> … end ID1218, Christian Schulte
Scoping in Patterns Revisited • The following PID= …, receive {P,…} when P==PID -> … end can be rewritten to PID= …, receive {PID,…} -> … end • Variables already introduced are not pattern variables but the values they are assigned to • whoa, this is ugly (my personal taste) ID1218, Christian Schulte
A Working RPC Client rpc(Server,Request) -> Server ! {self(),Request}, receive {Server,Response} -> Response end. • This is still easy… but correct… • but why: there can only be one pending reply • not so easy to see ID1218, Christian Schulte
The Registry • Register processes under names (atoms) • for example: clock, logger, … • Operations • register(Name,Pid) • unregister(Name) • whereis(Name) returns PID or undefined • registered() returns all registered names • Example register(a,PID), a ! M • As always: the registry is scary… ID1218, Christian Schulte
Summary & Outlook ID1218, Christian Schulte
Summary: Concurrency • Processes communicate by message sending • feature ordered mailbox • execute selective receive statements • messages buffered until removed by receive • are scheduled fairly • can use timeouts • Simple concurrency pattern • client – server • request – reply ID1218, Christian Schulte
Outlook: L05 • How can concurrent computations • synchronize with each other • cooperate • What are the properties of programs • with and • without message sending and message receipt ID1218, Christian Schulte