SLIDE 1 F undamen tal Structures
Computer Science I I 15-212-ML F all 1998 CONCURRENCY
SLIDE 2 Concurrency Op erations in a p rogram a re concurrent if they c
b e executed in pa rallel. Concurrent p rograms a re inherently nondeterministic. Concurrent p rogramming languages p rovide abstraction mechanisms fo r concurrency , with less
than using system-level p ro cesses. 2
SLIDE 3 F
Sequential Op erations Being fo rced to have sequential
erations can have disatrous eects fo r inherently concurrent applications. Example: the Unix xrn \lost connection to remote news server" feature. 3
SLIDE 4 Natural Places fo r Concurrent Programming
systems such as windo w managers and GUIs. User interaction can b e complex.
sp readsheet might p rovide an edito r, a windo w fo r graphical displa ys
data, and even a sp eech interface.
applications have \deadtime" b et w een input events when running.
application is
intensive, concurrency can mak e it resp
to input.
systems { each no de has its
state and control
Anything involving a net w
p roto cols. 4
SLIDE 5 Language Supp
Abstraction is essential to writing and maintaining soft w a re When it comes to concurrency , most languages do not p rovide useful abstractions Ra w p ro cess creation using fo rk() is p rovided in C 5
SLIDE 6 Reasoning Ab
Languages In SML there is a clean semantics that aids
reasoning
e 1 , ! true
e 2 , ! v
if e 1 then e 2 else e 2 , ! v With references, reasoning b ecomes mo re complicated let val memo = ref (fn () => raise Impossible) fun s'() = let val r = s() in memo := (fn () => r); r end in memo := s'; fn () => (!memo)() end 6
SLIDE 7 Concurrent Programming is Ha rd Sequential p rograms a re deterministic let val x = ref in x := !x + 1; x := !x + 2; print (!x) end Reasoning required when p rogramming with concurrency is much mo re complicated let val x = ref in (x := !x + 1) k (x := !x + 2); print (!x) end 7
SLIDE 8 Ingredients fo r Concurrency
mechanism fo r intro ducing sequential threads
control,
p ro cesses
w a y fo r p ro cesses to communicate
mechanism fo r p ro cesses to synchronize to restrict
execution and limit nondeterminism 8
SLIDE 9 Flavo rs
Concurrent Language Sha red-memo ry
imp erative features fo r interp ro cess communication
rate synchronization p rimitives to control access to sha red state.
Java Message-passing
mechanism fo r synchronization and communication
CML 9
SLIDE 10 Interference let val x = ref in (x := !x + 1) k (x := !x + 2); print (!x) end Interference can
when t w
ro cesses a re accessing critical regions
co de where assignments a re made Synchronization p rovides the mechanism fo r avoiding interference, b y allo wing a p ro cess to
a lo ck in a critical region. 10
SLIDE 11 Deadlo ck Consider the follo wing schematic
p ro cesses P and Q: P: acquire A; acquire B; compute; release B; release A; Q: acquire B; acquire A; compute; release A; release B; This can deadlo ck with P holding the lo ck
A and Q holding the lo ck
B. 11
SLIDE 12 Livelo ck No w consider P and Q dened as: P: Q: l: acquire A; l: acquire B; if (B is held) if (A is held) then (release A; goto l) then (release B; goto l) else acquire B else acquire A compute compute release B; release A release A; release B What might happ en here? 12
SLIDE 13 Threads in Java public interface Runnable f public abstract void run(); g public class Thread implements Runnable f public Thread(); public Thread(String name); ... public void run(); public void start() thro ws IllegalThreadStateException; public nal void stop(); public nal void suspend() thro ws SecurityException; public nal void resume() thro ws SecurityException; ... g 13
SLIDE 14 Threads in Java (con t) class PrimeThread extends Thread f long minPrime; PrimeThread(long minPrime) f this.minPrime = minPrime; g public void run() f // compute p rimes
... g g PrimeThread p = new PrimeThread(101); p.start(); 14
SLIDE 15 Threads in Java (con t)
synchronized metho d acquires a lo ck b efo re it executes.
a va riable is ever to b e assigned b y
thread and used b y another, all accesses to that va riable should b e synchronized.
cking is ca rried
using monito rs in the JVM.
mak es metho ds and blo cks atomic.
cking is not p revented. 15
SLIDE 16 Threads in Java (con t) public class Box f p rivate Object boxContents; public synchronized Object get() f Object contents = boxContents; boxContents = null; return contents; g public synchronized boolean put(Object contents)f if (boxContents != null) return false; boxContents = contents; return true; g g 16
SLIDE 17 Sha red Memo ry Mo del
eciency , but not co rrectness
\defensive p rogramming" (p rotect y
data from interference).
t with value-o riented p rogramming (ML) 17
SLIDE 18 Message-P assing Languages
cesses communicate b y sending messages across channels.
communication ma y either b e blo cking (o r synchronous)
non-blo cking (asynchronous) [4 p
metapho r: In asynchronous send,
the letter is in the mailb
the sender can p ro ceed with
tasks.
elephone metapho r: In synchronous send, the sender is tied up until his message is received.
message p assing is e asier to r e ason ab
18
SLIDE 19 Basic CML Primitives: Threads A thread is a CML p ro cess. Initially , there is a single thread but mo re can b e created using spawn: val spawn : (unit
unit)
thread id
a new thread to evaluate the function.
numb er
threads is unb
threads a re rep resented b y ML values, their sto rage can b e recycled b y the ga rbage collecto r. 19
SLIDE 20 Basic CML Primitives: Channels F
threads to b e useful, w e need w a ys to communicate b et w een them. F
communicating values
t yp e 'a, CML p rovides t yp e 'a chan The send and receive
erations a re val recv : 'a chan
'a val send : ('a chan * 'a)
unit Message passing is synchronous 20
SLIDE 21 Basic CML Primitives: Channels (con t) When a thread executes a send
receive
a channel, it blo cks until some
thread
the complementa ry communication. The message is then passed from sender to receiver, and the threads continue. Message passing involves b
communication and synchronization 21
SLIDE 22 Example: Reference Cells As a simple example
channels, as w ell as client-server p roto cols, w e'll implement the follo wing signature fo r mutable cells: signature CELL = sig t yp e 'a cell val cell : 'a
'a cell val get : 'a cell
'a val put : 'a cell * 'a
unit end 22
SLIDE 23 Example: Reference Cells (con t) structure Cell :> CELL = struct datat yp e 'a request = GET | PUT
'a datat yp e 'a cell = CELL
freqCh:'a request CML.chan, replyCh:'a CML.chang fun get (CELLfreqCh, replyChg) = (CML.send (reqCh, GET); CML.recv replyCh) fun put (CELLfreqCh, ...g, x) = CML.send (reqCh, PUT x) ... end 23
SLIDE 24 Example: Reference Cells (con t) structure Cell :> CELL = struct datat yp e 'a request = GET | PUT
'a datat yp e 'a cell = CELL
freqCh:'a request CML.chan, replyCh:'a CML.chang fun cell x = let val reqCh = CML.channel() val replyCh = CML.channel() fun loop x = (case (CML.recv reqCh)
GET => (CML.send (replyCh, x); loop x) | (PUT x') => loop x') in CML.spawn (fn () => loop x); CELL freqCh = reqCh, replyCh = replyChg end fun get (CELLfreqCh, replyChg) = (CML.send (reqCh, GET); CML.recv replyCh) fun put (CELLfreqCh, ...g, x) = CML.send (reqCh, PUT x) end 24
SLIDE 25 Example: Reference Cells (con t) This is an example
client-server st yle
concurrent p rogramming. Why is the implementation co rrect? Why can't multiple clients interfere with each
and receive each
messages, since they a re communicating
the same channel? 25
SLIDE 26 Example: Streams fun nats start = let val ch = CML.channel() fun count i = (CML.send(ch, i); count(i+1)) in CML.spawn (fn () => count start); ch end 26
SLIDE 27 Sieve
Eratosthenes fun filter (p, inCh) = let val
= CML.channel(); fun loop () = let val i = CML.recv inCh in if ((i mod p) <> 0) then CML.send (outCh, i) else (); loop() end in CML.spawn loop;
end 27
SLIDE 28 Sieve
Eratosthenes (con t) fun sieve() = let val primes = CML.channel() fun head ch = let val p = CML.recv ch in CML.send (primes, p); head (filter (p, ch)) end in CML.spawn (fn () => head (nats 2)); primes end Ho w do these streams dier from those w e built using susp ensions? 28
SLIDE 29 Datao w Net w
This is an example
a datao w net w
where the data moves from
p ro cess to another. Simplest example is pip eline where data moves along a chain
p ro cesses. 29
SLIDE 30 The Fib
Net w
[Picture
net w
here] 30
SLIDE 31 Fib
Net w
fun fibchannel () = let val
= CML.channel() val c1 = CML.channel() and c2 = CML.channel() and c3 = CML.channel() val c4 = CML.channel() and c5 = CML.channel() in delay (SOME 0) (c4, c5); copy (c2, c3, c4); add (c3, c5, c1); copy (c1, c2,
CML.send (c1, 1);
end 31
SLIDE 32 Fib
Net w
(con t) Implemented using innitely lo
threads: val forever : 'a
('a
'a)
unit fun forever init f = let fun loop s = loop (f s) in igno re (CML.spawn (fn () => loop init)) end 32
SLIDE 33 Fib
Net w
(con t) fun add (inCh1, inCh2,
= forever () (fn () => CML.send (outCh, (CML.recv inCh1) + (CML.recv inCh2))) fun delay init (inCh,
= forever init (fn NONE => SOME(CML.recv inCh) | (SOME x) => (CML.send(outCh, x); NONE)) fun copy (inCh,
= forever () (fn () => let val x = CML.recv inCh in CML.send(outCh1, x); CML.send(outCh2, x) end) 33
SLIDE 34 Fib
Net w
A Bug fun fibchannel () = let val
= CML.channel() val c1 = CML.channel() and c2 = CML.channel() and c3 = CML.channel() val c4 = CML.channel() and c5 = CML.channel() in delay (SOME 0) (c4, c5); copy (c2, c4, c3); add (c3, c5, c1); copy (c1, c2,
CML.send (c1, 1);
end 34
SLIDE 35 Fib
Net w
A Bug So, deadlo ck can b e very ha rd to gua rd against. The language can help: intro duce nondeterminism in the
blo cking communication
erations. Leads us to events 35
SLIDE 36 Events CML p rovides the t yp e constructo r fo r abstract synchronous
erations: t yp e 'a event An
returns a value
t yp e
it is synchronized
36
SLIDE 37 Events (con t) Events allo w us to manipulate multiple concurrent
erations without explicitly synchronizing
any sp ecic
Enables us to reason ab
and manipulate the nondeterminism in a p rogram select [ recvEvt chan1, recvEvt chan2 ] The thread blo cks at the select statement, w aiting to receive a message from either channel 37
SLIDE 38 Basic Event Op erations val sendEvt : ('a chan * 'a)
unit event val recvEvt : 'a chan
'a event val wrap : 'a event * ('a->'b)
'b event val select : 'a event list
'a The wrap function enables us to build up event values 38
SLIDE 39 Events in Java Events a re \b roadcast" and va rious classes
events can b e subscrib ed to b y \listening" to the b roadcast channel public abstract interface MouseListener extends EventListener f public abstract void mouseClicked (MouseEvent e); public abstract void mouseEntered (MouseEvent e); public abstract void mouseExited (MouseEvent e); public abstract void mousePressed (MouseEvent e); public abstract void mouseReleased (MouseEvent e); g Do es not supp
selection from a dynamically changing set
events. 39
SLIDE 40 Example: Reference Cells Using Events datat yp e 'a cell = CELL
fgetCh:'a CML.chan, putCh:'a CML.chang fun get (CELLfgetCh, ...g) = CML.recv getCh fun put (CELLfputCh, ...g, x) = CML.send (putCh, x) fun cell x = let val getCh = CML.channel() val putCh = CML.channel() fun loop x = select [ wrap (sendEvt(getCh, x), fn () => loop x), wrap (recvEvt putCh, loop) ] in CML.spawn (fn () => loop x); CELL fgetCh = getCh, putCh = putChg end 40
SLIDE 41 Concurrency and Computation Concurrency can enable mo re p
erful computation. Recall that there is no w a y to compute the disjunction
t w
p ro cedures in SML. Using pa rallel computation, ho w ever, w e can. Ho w? 41
SLIDE 42 P a rallel Or & Semi-Decision Pro cedures fun parallelOr (p, q) x = let val chp = CML.channel() val chq = CML.channel() fun decide pred ch = if pred(x) then CML.send(ch, true) else () in CML.spawn (fn () => decide p chp); CML.spawn (fn () => decide q chq); CML.select [ CML.recvEvt chp, CML.recvEvt chq ] end 42
SLIDE 43 Reference/Ackno wledgement Most
the material p resented here has b een adapted from the manuscript Concurr ent Pr
amming in ML b y John Repp y . The CML co de in these examples is cop yrighted, (c) 1998 b y Bell Labs, Lucent T echnologies. 43