Transcript Document
ITERATIVE COMPUTATIONS CONCURRENCY
Christian Schulte
Software and Computer Systems School of Information and Communication Technology KTH – Royal Institute of Technology Stockholm, Sweden ID1218 Lecture 04 2009-11-04
2
A Fourth Look
ID1218, Christian Schulte L04, 2009-11-04
A Better Length?
3
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 L04, 2009-11-04
Running
l/1
4
l([1,2,3]) ; → [1,2,3] CALL(l/1) ; → CALL(l/1) ; [1,2,3] → → → → → → 1+l([2,3]) l([2,3]) ; ADD 1+l([3]) ADD 1 l([2,3]) ADD ; ; 1 1 ; [2,3] CALL(l/1) ADD CALL(l/1) ADD ; [2,3] ; 1 1 → → 1 l([3]) ADD ADD l([3]) ADD ADD ; ; 1 1 1 → … requires stack space in the length of list ID1218, Christian Schulte L04, 2009-11-04
Running
l/2
5
l([1,2,3],0) ; → [1,2,3] 0 → → → → → CALL(l/2) ; 0 CALL(l/2) ; CALL(l/2) ; [1,2,3] 0 [1,2,3] l([2,3],0+1) ; [2,3] 0+1 0+1 CALL(l/2) CALL(l/2) ; [2,3] ; → → → → → → 0 1 ADD CALL(l/2) ; 1 ADD CALL(l/2) ; 0 [2,3] [2,3] ADD CALL(l/2) ; CALL(l/2) ; 1 0 [2,3] 1 [2,3] l([3],1+1) … ; requires constant stack space!
ID1218, Christian Schulte L04, 2009-11-04
Appending Two Lists
6
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 L04, 2009-11-04
Iterative Computations
7
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 L04, 2009-11-04
8
Concurrency
ID1218, Christian Schulte L04, 2009-11-04
The World Is Concurrent!
9
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 L04, 2009-11-04
Why Should We Care?
10
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 L04, 2009-11-04
Concurrent Programming Is Easy…
11
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 L04, 2009-11-04
Concurrency in Erlang
12
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 L04, 2009-11-04
Creating Processes
13
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 L04, 2009-11-04
Our First Process
14
loop() -> receive kill -> io:format("Aargh: dead...~n"); Other -> end.
io:format("Yummy: ~p~n",[Other]), loop() ID1218, Christian Schulte L04, 2009-11-04
Running the Process
15
> 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 L04, 2009-11-04
Processes Run Forever…
16
Why does process not run out of memory property of loop/0 ID1218, Christian Schulte L04, 2009-11-04
Primitives
17
Creating processes spawn(F) for function value F spawn(M,F,As) for function F in module M argument list As with Sending messages PID ! message Receiving messages receive … end with clauses Who am I?
self() returns the PID of the current process ID1218, Christian Schulte L04, 2009-11-04
Processes
18
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 L04, 2009-11-04
Message Sending
19
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 L04, 2009-11-04
Message Receipt
20
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 first message statement has a matching clause for the 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 L04, 2009-11-04
Receive Example
21
mailbox head a b c d a b d a d 1.
2.
1.
2.
3.
receive c -> … end receive d -> …; b -> … end receive M -> … end ID1218, Christian Schulte L04, 2009-11-04 d 3.
Receiving Multiple Messages
22
seq() -> receive a -> receive b -> … end; c -> … end.
With other words: processes can use different receive statements What does it mean is a is a sent before b ?
received before b ?
ID1218, Christian Schulte L04, 2009-11-04
Receive With Timeouts
23
receive … after Time -> Expr end If no matching message arrived within milliseconds, evaluate Expr Time If only after Time clause present, process sleeps for milliseconds ID1218, Christian Schulte L04, 2009-11-04
Flushing the Mailbox
24
flush() -> receive _ -> flush() after 0 -> true end.
ID1218, Christian Schulte L04, 2009-11-04
Priority Receipt
25
priority() -> receive alarm -> … after 0 -> receive M -> …, priority() end end.
ID1218, Christian Schulte L04, 2009-11-04
Timed Repeater
26
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 L04, 2009-11-04
Different Message Types
27
receive {a, … } -> … ; {b, … } -> … … end Use tuples as messages first field of tuple describes message type ID1218, Christian Schulte L04, 2009-11-04
28
Client Server Architectures
ID1218, Christian Schulte L04, 2009-11-04
Client Server
29
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 L04, 2009-11-04
How to Reply: RPC
30
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 L04, 2009-11-04
RPC Server
31
serve() -> receive {Client,Request} -> Response = process(Request), Client ! Response, end.
serve() ID1218, Christian Schulte L04, 2009-11-04
RPC Client
32
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 L04, 2009-11-04
Who Talks To Me?
33
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 L04, 2009-11-04
Scoping in Patterns Revisited
34
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 L04, 2009-11-04
A Working RPC Client
35
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 L04, 2009-11-04
The Registry
36
Register processes under names (atoms) for example: clock , logger , … Operations register(Name,Pid ) unregister(Name) whereis(Name) registered() returns PID or undefined returns all registered names Example register(a,PID), a ! M As always: the registry is scary… ID1218, Christian Schulte L04, 2009-11-04
37
Summary & Outlook
ID1218, Christian Schulte L04, 2009-11-04
Summary: Concurrency
38
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 L04, 2009-11-04
Outlook: L05
39
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 L04, 2009-11-04