concurrency ©magee/kramer february 05, 2007 claus brabrand [email protected] university of...

51
Concurrency ©Magee/ Kramer February 05, 2007 Claus Brabrand [email protected] University of Aarhus Concurrency Spring 2007

Post on 15-Jan-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Claus Brabrand

[email protected]

University of Aarhus

Concurrency

Spring 2007

Page 2: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Concurrency

State Models and Java Programs

Jeff Magee and Jeff Kramer

(adapted by Claus Brabrand)

Page 3: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Models

Model = simplified representation of the real world

Focuses on concurrency aspects (of the program)

everything else abstracted away

Based on Labelled Transition Systems (LTS ):

Described textually as Finite State Processes

(FSP ):

Aka. Finite StateMachine (FSM )

SWITCH = OFF,OFF = (on -> ON),ON = (off-> OFF).

on

off

0 1

Page 4: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Models (Cont’d)

Engineers use models to gain confidence in the adequacy and validity of a proposed design

Model = simplified representation of the real world

Analysed/Displayed by LTS Analyser

(LTSA ):

Runtime testing (animation) of model to visualise

behaviour

Compile-time verification of safety properties

Page 5: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Testing vs. Verification

What does:

safety / testing / verification

... mean? (e.g., for the cruise controller)

Cruise controlsystem:

Page 6: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Programming Practice

Java:

widely available, generally accepted, and portable

provides good concurrency abstractions

Thus, we shall use Java for all:

Illustrative examples, demonstrations, and exercises

”Toy problems”:

crystallize concurrency programming issues and problems!

Page 7: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Concepts:

Conceptual ideas behind concurrency problems and

solution techniques

Models:

Provide insight into concurrent behaviour and aid

reasoning about particular designs

Practice:

Programming practice and experience

Course Objective

This course is divided into concepts, models and practice involved in designing concurrent software.

Page 8: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Course Outline

Processes and Threads

Concurrent Execution

Shared Objects & Interference

Monitors & Condition Synchronization

Deadlock

Safety and Liveness Properties

Model-based Design

Concepts

Models

Practice

Page 9: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Web-Based Course Material

Java examples and demonstration programs

LTS models for the examples

Labelled Transition System Analyser (LTSA) for visualisation, animation, and verification

http://www.doc.ic.ac.uk/~jnm/book/

Page 10: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Summary

Concepts:We adopt a model-based approach for the design and

construction of concurrent programs

Models:We use finite state models to represent concurrent

behaviour

Practice:We use Java for constructing concurrent programs

Examples are used to illustrate the concepts, models, and demonstration programs

Page 11: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Chapter 2

Processes & Threads

Page 12: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Concurrent Processes

Model: process ~Finite State Processes (FSP)

Practice: process ~Java thread

Concept: process ~sequences of actions

We structure complex systems as sets of simpler activities, each represented as a (sequential) process

Processes can be concurrent

Designing concurrent software: - complex and error prone

We need rigorous engineering approach!

Page 13: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Processes and Threads

Concepts: A Process – a unit of sequential execution

Models: Finite State Processes (FSP) to model a process as sequences of actions

Labelled Transition Systems (LTS) to analyse, display, and animate

behaviour

Practice: Java thread

Page 14: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

2.1 Modelling Processes

Models are described using state machines, known as Labelled Transition Systems (LTS)

These are described textually as Finite State Processes (FSP)

Analysed/Displayed by the LTS Analyser (LTSA)

FSP - algebraic form

LTS - graphical form

SWITCH = OFF,OFF = (on -> ON),ON = (off-> OFF).

on

off

0 1

Page 15: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - STOP

STOP is the inactive process, doing absolutely nothing.

INACTIVE = STOP.

INACTIVE state machine (terminating process)

FSP:

LTS:

Note that it offers:the prototypical behavior of a deadlocked process (that cannot proceed any further in its execution)

Page 16: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - action prefix

If x is an action and P a process then (x-> P) describes a process that initially engages in the action x and then behaves exactly as described by P.

MATCH = (strike -> STOP).

Convention: actions begin with lowercase letters

PROCESSES begin with uppercase letters

FSP:

LTS:

Page 17: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Action Prefix (cont’d)

If x is an action and P a process then (x-> P) describes a process that initially engages in the action x and then behaves exactly as described by P.

COMPLEX_MATCH = (take -> strike -> STOP).

FSP:

LTS:

Page 18: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Action Prefix (cont’d)

If x is an action and P a process then (x-> P) describes a process that initially engages in the action x and then behaves exactly as described by P.

DISPENSER = (coin -> coke -> STOP).

FSP:

LTS:

Input vs. Output actions ?- From Dispenser’s perspective ?- From Environment’s perspective ?

Page 19: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Modeling Processes

A process is modelled by a sequential program.

It is modelled as a finite state machine which transits from state to state by executing a sequence of atomic actions.

a light switch LTS

onoffonoffonoff ……….a sequence of actions or trace

on

off

0 1

Page 20: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - action prefix & recursion

SWITCH = OFF,OFF = (on -> ON),ON = (off-> OFF).

Repetitive behaviour uses recursion:

Substituting to get a more succinct definition:

SWITCH = OFF,OFF = (on ->(off->OFF)).

Again?:

SWITCH = (on->off->SWITCH).

on

off

0 1

Page 21: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Animation using LTSA

Ticked actions are eligible for selection.

In the LTS, the last action is highlighted in red.

The LTSA animator can be used to produce a trace.

on

off

0 1

Page 22: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - action prefix

TRAFFICLIGHT = (red->orange->green->orange -> TRAFFICLIGHT).

LTS?

Trace(s)?

FSP model of a traffic light:

redorangegreenorangeredorangegreen …

red orange green

orange

0 1 2 3

What would the LTS look like for?:T = (red->orange->green->orange->STOP).

Page 23: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - choice

If x and y are actions then (x-> P | y-> Q) describes a process which initially engages in either of the actions x or y. After the first action has occurred, the subsequent behavior is described by P if the first action was x; and Q if the first action was y.

Who or what makes the choice?

Is there a difference between input and output actions?

Page 24: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - choice

DRINKS = (red->coffee->DRINKS |blue->tea->DRINKS ).

LTS generated using LTSA:

Possible traces?

FSP model of a drinks machine :

red

blue

coffee

tea

0 1 2

Page 25: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Non-deterministic choice

Process (x -> P | x -> Q) describes a process which engages in x and then non-deterministically behaves as either P or Q.COIN = (toss->HEADS|toss->TAILS),HEADS= (heads->COIN),TAILS= (tails->COIN).

Tossing a coin.

toss

toss

heads

tails

0 1 2

Possible traces?

LTS?

Page 26: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Example: Modelling unreliable communication channel

How do we model an unreliable communication channel which accepts in actions and if a failure occurs produces no output, otherwise performs an out action?

CHAN = (in->CHAN |in->out->CHAN ).

in

in

out

0 1

Use non-determinism...:

Page 27: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Single slot buffer that inputs a value in the range 0 to 3 and then outputs that value:

FSP - indexed processes and actions

BUFF = (in[i:0..3]->out[i]-> BUFF).

Could we have made this process w/o using the indices?

BUFF = (in_0->out_0->BUFF |in_1->out_1->BUFF |in_2->out_2->BUFF |in_3->out_3->BUFF ).

Def/Use (as in programming languages)

BUFF = (in[0]->out[0]->BUFF |in[1]->out[1]->BUFF |in[2]->out[2]->BUFF |in[3]->out[3]->BUFF ).

...or...:

Page 28: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Indices (cont’d)

BUFF = (in[0]->out[0]->BUFF |in[1]->out[1]->BUFF |in[2]->out[2]->BUFF |in[3]->out[3]->BUFF).

LTS?

BUFF = (in[i:0..3]->out[i]-> BUFF). or

Page 29: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - indexed processes and actions (cont’d)

BUFF = (in[i:0..3]->out[i]-> BUFF).

equivalent to

BUFF = (in[i:0..3]->OUT[i]),

OUT[i:0..3] = (out[i]->BUFF).

equivalent to

BUFF = (in[i:0..3]->OUT[i]),

OUT[j:0..3] = (out[j]->BUFF).

Page 30: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

const N = 1

SUM = (in[a:0..N][b:0..N]->TOTAL[a+b]),TOTAL[s:0..2*N] = (out[s]->SUM).

FSP - constant & addition

index expressions to model calculation: in.0.0

in.0.1in.1.0

in.1.1

out.0

out.1

out.2

0 1 2 3

Page 31: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

const N = 1range T = 0..Nrange R = 0..2*N

SUM = (in[a:T][b:T]->TOTAL[a+b]),TOTAL[s:R] = (out[s]->SUM).

FSP - constant & range declaration

index expressions to model calculation: in.0.0

in.0.1in.1.0

in.1.1

out.0

out.1

out.2

0 1 2 3

Page 32: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - guarded actions

The choice (when B x -> P | y -> Q) means that when the guard B is true then the actions x and y are both eligible to be chosen, otherwise if B is false then the action x cannot be chosen.

COUNT (N=3) = COUNT[0],COUNT[i:0..N] = (when(i<N) inc->COUNT[i+1] |when(i>0) dec->COUNT[i-1] ).

inc inc

dec

inc

dec dec

0 1 2 3

LTS?

Could we have made this process w/o using the guards?

Page 33: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - guarded actions

COUNTDOWN (N=3) = (start->COUNTDOWN[N]),COUNTDOWN[i:0..N] =

(when(i>0) tick->COUNTDOWN[i-1] |when(i==0)beep->STOP

|stop->STOP ).

A countdown timer which beeps after N ticks, or can be stopped.

start

stop

tick

stop

tick

stop

tick beepstop

0 1 2 3 4 5

Page 34: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - guarded actions

What is the following FSP process equivalent to?

const False = 0P = (when (False) do_anything->P).

Answer:

STOP

Page 35: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP - process alphabets

The alphabet of a process is the set of actions in which it can engage.

Alphabet extension can be used to extend the implicit alphabet of a process:

WRITER = (write[1]->write[3]->WRITER) +{write[0..3]}.

Alphabet of WRITER is the set {write[0..3]}

(we make use of alphabet extensions in later chapters)

Page 36: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Practice

Threads in Java

Page 37: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

2.2 Implementing processes

Modelling processes as finite state machines using FSP/LTS.

Implementing threads in Java.

Note: to avoid confusion, we use the term process when referring to the models, and thread when referring to the

implementation in Java.

Page 38: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

1 Process:

Data: The heap (global, heap allocated data)Code: The program (bytecode)Stack: The stack (local data, call stack)Descriptor: program counter, stack pointer, …

One Process

data code

descriptorstack

Page 39: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Implementing processes - the OS view

A (heavyweight) process in an operating system is represented by its code, data and the state of the machine registers, given in a descriptor. In order to support multiple (lightweight) threads of control, it has multiple stacks, one for each thread.

data

A multi-threaded process

code descriptor

descr.

stack

Thread 1

descr.

stack

Thread 2

descr.

stack

Thread n

. . . . . .

Page 40: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Threads in Java

A Thread class manages a single sequential thread of control. Threads may be created and deleted dynamically.

Thread

run()

MyThread

run()

The Thread class executes instructions from its method run(). The actual code executed depends on the implementation provided for run() in a derived class.

class MyThread extends Thread {public void run() {

//......}

}

Thread x = new MyThread();

Page 41: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Threads in Java (cont’d)

Since Java does not permit multiple inheritance, we often implement the run() method in a class not derived from Thread but from the interface Runnable.

Runnable

run()

MyRun

run()

Threadtarget

public interface Runnable { public abstract void run();}

class MyRun implements Runnable { public void run() { //...... }}

Thread x = new Thread(new MyRun());

Page 42: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Thread Life-Cycle

Java Thread Life-Cycle:

RunningRunning schedule yield()

• sleep(kmsec) wakeup• wait() notify()• I/O block unblock• suspend() resume()

• stop()• destroy()• run() terminates

• start()

Page 43: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Example: Countdown timer

Model <-> Impl.

Page 44: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

CountDown timer example

const N = 3COUNTDOWN = (start->COUNTDOWN[N]),COUNTDOWN[i:0..N] =

(when(i>0) tick->COUNTDOWN[i-1] |when(i==0) beep->STOP

|stop->STOP ).

Implementation in Java?

Page 45: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

CountDown class

public class CountDown implements Runnable { Thread counter; int i; final static int N = 3;

public void run() { ... } public void start() { ... } public void stop() { ... } protected void tick() { ... } protected void beep() { ... }}

start

stop

tick

stop

tick

stop

tick beepstop

0 1 2 3 4 5

Page 46: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

CountDown class - start(), stop() and run()

public void start() { counter = new Thread(this); i = N; counter.start(); }

public void stop() { counter = null; }

public void run() { while(true) { if (i>0) { tick(); --i; } if (i==0) { beep(); return;} if (counter == null) return; } }

COUNTDOWN Modelstart -> CountDown[N]

stop -> STOP

COUNTDOWN[i] process recursion as a while loop when(i>0) tick -> CD[i-1] when(i==0)beep -> STOP stop->STOP

STOP ~ run() terminates

Page 47: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

CountDown class – the output actions: tick() and beep()

protected void tick() { <<emit tick sound>> try { Thread.sleep(1000); } catch(InterruptedException iex){ // ignore (in this toy-example) } }

protected void beep() { <<emit beep sound>> }

Page 48: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Summary

Conceptsprocess - unit of concurrency, execution of a program

ModelsLTS to model processes as state machines - sequences

of atomic actions

FSP to specify processes using prefix “->”, choice ” | ”

and recursion

Practice Java threads to implement processes

Thread lifecycle

(created, running, runnable, non-runnable,

terminated)

Page 49: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

Process Exercises (FSP)

[MK 2.1]Simple introductory FSP exercises

[MK 2.2]Variable* *) “read” reads the last value written.

[MK 2.3]Bistable

[MK 2.4]Sensor

Thread Life-Cycle (as an FSP process)

Page 50: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

FSP Exercise [MK 2.5]

This week’s hand-in:

SUGAROLA:

A drinks dispensing machine charges 15p for a can of Sugarola.The machine accepts coins with denominations 5p, 10p, and 20pand gives change. Model the machine as an FSP process, DRINKS.

Page 51: Concurrency ©Magee/Kramer February 05, 2007 Claus Brabrand brabrand@daimi.au.dk University of Aarhus Concurrency Spring 2007

Concurrency ©Magee/KramerFebruary 05, 2007

The End

Questions?

See you next Monday..