Скачать презентацию Safe Concurrent Programming In Java with CSP Taken Скачать презентацию Safe Concurrent Programming In Java with CSP Taken

26bcf89fe8c432ce60f23b9e83bcee34.ppt

  • Количество слайдов: 79

Safe Concurrent Programming In Java with CSP Taken from a presentation by Chris Nevison Safe Concurrent Programming In Java with CSP Taken from a presentation by Chris Nevison Colgate University

Overview Why Concurrent Programming Concurrent Threads in Java Monitors Concurrent Sequential Processes (CSP) CSP Overview Why Concurrent Programming Concurrent Threads in Java Monitors Concurrent Sequential Processes (CSP) CSP in Java Examples of Concurrent Programs using CSP Data Flow using CSP The Future ?

Why Concurrent Programming? Sequential programming is artificial – Most real world situations occur concurrently Why Concurrent Programming? Sequential programming is artificial – Most real world situations occur concurrently – Question should be “why sequential programming? ” Many programs are more naturally constructed as concurrent programs Multiple processors, client-server interactions are concurrent Parallel computing for performance

Concurrent Threads in Java Extend class Thread or Implement interface Runnable -- Preferred! start Concurrent Threads in Java Extend class Thread or Implement interface Runnable -- Preferred! start member functions starts thread, runs member function run Memory is shared -- threads communicate by reading/writing to same memory locations Need Synchronization to avoid race conditions Threads run concurrently – time-sliced on a single processor – in parallel on an SMP (depending on OS)

Thread States New -- declared, not yet started Runnable -- ready to run Running Thread States New -- declared, not yet started Runnable -- ready to run Running -- currently running Blocked – blocked on I/O, wait on Monitor, sleep, join Suspended -- by call to suspend Suspended-Blocked -- suspend called while blocked Dead -- run ends, stop called

Thread States stop start New Runnable descheduled run ends Running yield stop Dead scheduled Thread States stop start New Runnable descheduled run ends Running yield stop Dead scheduled notify / notifyall sleep expires I/O completes join completes wait sleep join I/O stop Blocked self control scheduler external control

Example Problem: “unidirectional TSP” (Hartley) Given a matrix of costs, a path through the Example Problem: “unidirectional TSP” (Hartley) Given a matrix of costs, a path through the matrix is a sequence of cells in the matrix, such that the cell on the path in column k+1 is in the same or a neighboring row to the cell on the path in column k (where the first and last row wrap around). The unidirectional TSP is the problem of finding the least cost path from the first to the last column in the matrix.

Example Problem: “unidirectional TSP” (Hartley) 12 10 5 11 9 6 6 4 9 Example Problem: “unidirectional TSP” (Hartley) 12 10 5 11 9 6 6 4 9 7 8 9 5 8 8 3 Least Cost Path

Example Problem: “unidirectional TSP” (Hartley) 12 27 5 15 9 12 6 6 10 Example Problem: “unidirectional TSP” (Hartley) 12 27 5 15 9 12 6 6 10 25 11 19 6 10 4 4 9 25 8 16 5 8 8 8 7 22 9 17 8 11 3 3

unidirectional TSP parallel control Proc 0 12 5 9 6 Proc 1 10 11 unidirectional TSP parallel control Proc 0 12 5 9 6 Proc 1 10 11 6 4 Proc 2 9 8 7 8 Proc 3 7 9 8 3

class TSPRow. Solver extends My. Object implements Runnable{ private int my. Row = 0; class TSPRow. Solver extends My. Object implements Runnable{ private int my. Row = 0; private Matrix cost. Mat = null; private Matrix tot. Mat = null; private Matrix dir. Mat = null; private Thread t = null; public TSPRow. Solver(int row, Matrix cost, Matrix tot, Matrix dir){ my. Row = row; cost. Mat = cost; tot. Mat = tot; dir. Mat = dir; t = new Thread(this); t. start(); }

public void run(){ // initialize values int col = num. C - 1; tot. public void run(){ // initialize values int col = num. C - 1; tot. Mat. set. Val(my. Row, col, cost. Mat. val(my. Row, col));

for(col = col - 1; col >= 0; col--){ up = (my. Row - for(col = col - 1; col >= 0; col--){ up = (my. Row - 1 + num. R) % num. R; dn = (my. Row + 1) % num. R; up. Val = tot. Mat. val(up, col+1); row. Val = tot. Mat. val(my. Row, col+1); dn. Val = tot. Mat. val(dn, col+1); if((up. Val < row. Val) && (up. Val < dn. Val)){ tot. Mat. set. Val(my. Row, col, up. Val + cost. Mat. val(my. Row, col)); dir. Mat. set. Val(my. Row, col, up); } else if(dn. Val < row. Val && dn. Val <= up. Val){ // set tot. Mat and dir. Mat} else{// row. Val is largest, set tot. Mat, dir. Mat } }

unidirectional TSP No Control -- Race Condition 12 27 0 5 15 0 9 unidirectional TSP No Control -- Race Condition 12 27 0 5 15 0 9 12 0 6 6 10 18 11 19 0 0 6 10 0 4 9 17 0 8 5 8 0 8 8 7 9 17 0 8 3 15 0 8 0 11 0 4 3

Monitors in Java Key word synchronized Only one thread can “possess” monitor at a Monitors in Java Key word synchronized Only one thread can “possess” monitor at a time When conditions are not ready Thread can wait – thread blocks – Another thread calls notify or notifyall » On notify one waiting process becomes runnable » On notifyall waiting processes become runnable

Example: Barrier Synchronization A set of concurrent threads are included in the barrier Each Example: Barrier Synchronization A set of concurrent threads are included in the barrier Each included thread checks the barrier at the synchronization point No thread can pass the synchronization point until all threads in the barrier have reached it.

class Barrier{ private int release. Num; private int count; Barrier(int num){ release. Num = class Barrier{ private int release. Num; private int count; Barrier(int num){ release. Num = num; count = 0; } public synchronized void check(){ count++; if(count < release. Num){ try { wait(); } catch(Interrupted. Exception e){} } else{ count = 0; notify. All(); } } }

class TSPRow. Solver extends My. Object implements Runnable{ // other declarations and constructor public class TSPRow. Solver extends My. Object implements Runnable{ // other declarations and constructor public void run(){ // initialization tot. Mat. set. Val(my. Row, col, cost. Mat. val(my. Row, col)); for(col = col - 1; col >= 0; col--){ bar 1. check(); // includes all rows // computation } bar 2. check(); // includes all rows and main } }

Alternate Solution Synchronize each row to its neighbors Needs a monitor for each row Alternate Solution Synchronize each row to its neighbors Needs a monitor for each row Potentially more efficient – lets rows run further before blocking

Classic Problem: Producer-Consumers with Buffer accessed by both producer and consumers – critical section Classic Problem: Producer-Consumers with Buffer accessed by both producer and consumers – critical section for update of contents of buffer – consumer must wait if buffer is empty Use monitor to control access to buffer – Following uses adaptation of buffer (cubbyhole) solution given in Sun documentation

“Wot, No Chickens!” Peter Welch, University of Kent Five Philosophers (consumers) – Think – “Wot, No Chickens!” Peter Welch, University of Kent Five Philosophers (consumers) – Think – Go to Canteen to get Chicken for dinner – Repeat Chef (producer) – produces four chickens at a time and delivers to canteen

“Wot, No Chickens!” Philosopher 0 is greedy -- never thinks Other philosophers think 3 “Wot, No Chickens!” Philosopher 0 is greedy -- never thinks Other philosophers think 3 time units before going to eat Chef takes 2 time units to cook four chickens Chef takes 3 time units to deliver chickens – occupies canteen while delivering Simplified code follows -- leaves out exception handling try-catch

class Canteen { private int n_chickens = 0; public synchronized int get(int id) { class Canteen { private int n_chickens = 0; public synchronized int get(int id) { while (n_chickens == 0) { wait(); // Wot, No Chickens! } n_chickens--; // Those look good. . . one please return 1; } public synchronized void put(int value) { Thread. sleep(3000); // delivering chickens. . n_chickens += value; notify. All (); // Chickens ready! } }

class Chef extends Thread { private Canteen canteen; public Chef (Canteen canteen) { this. class Chef extends Thread { private Canteen canteen; public Chef (Canteen canteen) { this. canteen = canteen; start (); } public void run () { int n_chickens; while (true) { sleep (2000); // Cooking. . . n_chickens = 4; canteen. put (n_chickens); } } }

class Phil extends Thread { private int id; private Canteen canteen; public Phil(int id, class Phil extends Thread { private int id; private Canteen canteen; public Phil(int id, Canteen canteen) { this. id = id; this. canteen = canteen; start (); } public void run() { int chicken; while (true) { if (id > 0) { sleep(3000); // Thinking. . . } chicken = canteen. get(id); // Gotta eat. . . } // mmm. . . That's good } }

class College { public static void main (String argv[]) { int n_philosophers = 5; class College { public static void main (String argv[]) { int n_philosophers = 5; Canteen canteen = new Canteen (); Chef chef = new Chef (canteen); Phil[] phil = new Phil[n_philosophers]; for (int i = 0; i < n_philosophers; i++) { phil[i] = new Phil (i, canteen); } } }

“Wot, No Chickens!” Library P 1 Waiting Outside Canteen P 0 P 2 P “Wot, No Chickens!” Library P 1 Waiting Outside Canteen P 0 P 2 P 3 P 4 Wait Pickup Delivery Inside Cooking Chef

“Wot, No Chickens!” Library Waiting Outside P 0 P 1 P 2 Chef P “Wot, No Chickens!” Library Waiting Outside P 0 P 1 P 2 Chef P 2 P 3 P 4 Cooking Canteen P 4 P 0 Wait Pickup Delivery Inside Chef

“Wot, No Chickens!” Library Waiting Outside P 0 P 1 P 1 P 2 “Wot, No Chickens!” Library Waiting Outside P 0 P 1 P 1 P 2 P 3 P 4 Canteen P 3 P 4 P 0 Wot No P 4 Chickens! P 3 P 2 P 1 Wait Pickup Delivery Inside Cooking Chef

Problems with Java Monitors Semantics of Notify / Notify. All ? ? ? Breaks Problems with Java Monitors Semantics of Notify / Notify. All ? ? ? Breaks O-O model – Threads are controlled by calling functions inside monitor – Depend on notification by other threads – Multiple monitors can easily lead to deadlock – Monitors can easily lead to starvation – Global ! knowledge needed to adequately coordinate multiple monitors

Communicating Sequential Processes CSP Anthony Hoare, 1978 Processes (concurrent threads) – run sequential code Communicating Sequential Processes CSP Anthony Hoare, 1978 Processes (concurrent threads) – run sequential code – communicate process-to-process via channels Channels are point-to-point and synchronous (unbuffered) – standard is one-to-one, but many-to-one, one-tomany, and many-to-many have been implemented – Buffering can easily be added.

Communicating Sequential Processes Control – Sequential (default, can also be explicit – Parallel » Communicating Sequential Processes Control – Sequential (default, can also be explicit – Parallel » a set of processes run to completion to complete a parallel construct – Alternative » allows selection of first channel ready to communicate » theoretically any communication could be included, in practice only reads from channels

Occam 2 Language designed specifically for parallel computing using the CSP model Implemented on Occam 2 Language designed specifically for parallel computing using the CSP model Implemented on the Transputer, a chip designed for efficient on-chip (time-sliced) concurrency and communications with other transputers via channels Proves efficacy of CSP model

Java with CSP (JCSP) (University of Kent) A library of CSP constructs – Written Java with CSP (JCSP) (University of Kent) A library of CSP constructs – Written in pure Java – Provides CSP tools easy to use in Java – Hides difficult Monitor synchronization Utilities – Common modular JCSP constructs – facilitates Data-Flow style of programming JCSP AWT – extends Java AWT to use JCSP Channels

Synchronised Communication A c c ! 42 B c? x A may write on Synchronised Communication A c c ! 42 B c? x A may write on c at any time, but has to wait for a read. B may read from c at any time, but has to wait for a write. A (c) || B (c)

Synchronised Communication A c B c? x c ! 42 Only when both A Synchronised Communication A c B c? x c ! 42 Only when both A and B are ready can the communication proceed over the channel c. A (c) || B (c)

‘Legoland’ Catalog in out Id. Int (in, out) in 0 in 1 + n ‘Legoland’ Catalog in out Id. Int (in, out) in 0 in 1 + n Succ. Int out Succ. Int (in, out) in out 0 out 1 Plus. Int (in 0, in 1, out) in in out Prefix. Int (n, in, out) Delta 2 Int (in, out 0, out 1) in Tail. Int out Tail. Int (in, out)

‘Legoland’ Catalog _ This is a catalog of fine-grained processes think of them as ‘Legoland’ Catalog _ This is a catalog of fine-grained processes think of them as pieces of hardware (e. g. chips). They process data (ints) flowing through them. _ They are presented not because we suggest working at such fine levels of granularity … _ They are presented in order to build up fluency in working with parallel logic.

in Id. Int out Id. Int (in, out) = in? x --> out!x --> in Id. Int out Id. Int (in, out) = in? x --> out!x --> Id. Int (in, out) in Succ. Int out Succ. Int (in, out) = in? x --> out!(x + 1) --> Succ. Int (in, out) in 0 in 1 + out Note the parallel input Plus. Int (in 0, in 1) = (in 0? x 0 --> SKIP || inl? x 1 --> SKIP); out!(x 0 + x 1) --> Plus. Int (in 0, in 1, out)

out 0 in Note the parallel output out 1 Delta 2 Int (in, out out 0 in Note the parallel output out 1 Delta 2 Int (in, out 0, out 1) = in? x --> (out 0!x --> SKIP || out 1!x --> SKIP); Delta 2 Int (in, out 0, out 1) in n out Prefix. Int (n, in, out) = out!n --> Id. Int (in, out) in Tail. Int out Tail. Int (in, out) = in? x --> Id. Int (in, out)

A Blocking FIFO Buffer in Id. Int c[0] Id. Int c[1] c[n-2] Id. Int A Blocking FIFO Buffer in Id. Int c[0] Id. Int c[1] c[n-2] Id. Int Fifo (n) Fifo (n, in, out) = Id. Int (in, c[0]) || ([||i = 0 FOR n-2] Id. Int (c[i], c[i+1])) || Id. Int (c[n-2], out) Note: this is such a common idiom that it is provided as a (channel) primitive in JCSP. out

Fibonacci Prefix(1) Prefix(0) Plus Delta Tail Delta Fibonacci Prefix(1) Prefix(0) Plus Delta Tail Delta

Java with CSP (JCSP) (University of Kent) A library of CSP constructs – Written Java with CSP (JCSP) (University of Kent) A library of CSP constructs – Written in pure Java – Provides CSP tools easy to use in Java – Hides difficult Monitor synchronization Utilities – Common modular JCSP constructs – facilitates Data-Flow style of programming JCSP AWT – extends Java AWT to use JCSP Channels

JCSP constructs CSProcess Interface, comparable to Runnable must implement run() function Channels Various types. JCSP constructs CSProcess Interface, comparable to Runnable must implement run() function Channels Various types. As parameters can specify read only (Channel. Input) or write-only (Channel. Output) functions read() and write(object) Declared and passed as parameters to CSProcess class constructors Parallel A CSProcess which takes an array of other CSProcesses and runs them in parallel, terminates when all constituent processes complete run.

class Identity implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out; public Identity(Channel. class Identity implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out; public Identity(Channel. Input. Int in, Channel. Output. Int out){ this. in = in; this. out = out; } public void run(){ while(true){ int item = in. read(); out. write(item); } } }

class Prefix implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out; int first; class Prefix implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out; int first; public Prefix(int first, Channel. Input. Int in, Channel. Output. Int out){ this. in = in; this. out = out; this. first = first; } public void run(){ out. write(first); new Identity(in, out). run(); } }

class Tail implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out; public Tail(Channel. class Tail implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out; public Tail(Channel. Input. Int in, Channel. Output. Int out){ this. in = in; this. out = out; } public void run(){ in. read(); new Identity(in, out). run(); } }

class Plus implements CSProcess{ Channel. Input. Int in 1; Channel. Input. Int in 2; class Plus implements CSProcess{ Channel. Input. Int in 1; Channel. Input. Int in 2; Channel. Output. Int out; Process. Read. Int r 1; Process. Read. Int r 2; public Plus(Channel. Input. Int in 1, Channel. Input. Int in 2, Channel. Output. Int out){ this. in 1 = in 1; this. in 2 = in 2; this. out = out; r 1 = new Process. Read. Int(in 1); r 2 = new Process. Read. Int(in 2); } public void run(){ while(true){ new Parallel( new CSProcess[]{r 1, r 2}). run(); out. write(r 1. value + r 2. value); } } }

class Delta implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out 1; Channel. class Delta implements CSProcess{ Channel. Input. Int in; Channel. Output. Int out 1; Channel. Output. Int out 2; public Delta(Channel. Input. Int in, Channel. Output. Int out 1, Channel. Output. Int out 2){ this. in = in; this. out 1 = out 1; this. out 2 = out 2; } public void run(){ while(true){ int item = in. read(); new Parallel( new CSProcess[]{ new Proc. Write. Int(out 1, item), new Proc. Write. Int(out 2, item) }). run(); } } }

Fibonacci Prefix(1) Prefix(0) Plus Delta Tail Delta Fibonacci Prefix(1) Prefix(0) Plus Delta Tail Delta

class Fibonacci implements CSProcess{ Channel. Output. Int out; public Fibonacci(Channel. Output. Int out){ this. class Fibonacci implements CSProcess{ Channel. Output. Int out; public Fibonacci(Channel. Output. Int out){ this. out = out; } public void run(){ One 2 One. Channel. Int One 2 One. Channel. Int P 1 to. P 0 to. D 1 D 0 to. T Tto. Plus D 1 to. Plusto. P 1 = = = = new new One 2 One. Channel. Int; One 2 One. Channel. Int; new Parallel( CSProcess[]{ Prefix(1, Plusto. P 1, P 1 to. P 0), Prefix(0, P 1 to. P 0, P 1 to. D 0), Delta(P 1 to. D 0, D 0 to. D 1, D 0 to. T), Delta(D 0 to. D 1, out, D 1 to. Plus), Tail(D 0 to. T, Tto. Plus), Plus(Tto. Plus, D 1 to. Plus, Plusto. P 1) }). run(); } }

Unidirectional TSP Using JCSP Circuit Up Down Master. To. Row. Solver 0 Row. Solver Unidirectional TSP Using JCSP Circuit Up Down Master. To. Row. Solver 0 Row. Solver 1 Row. Solver 2 Row. Solver 3 M a s t e r Row. To. Master

class tspcircuit implements CSProcess{ private Matrix costmat; public tspcircuit(Matrix costmat){ this. costmat = costmat; class tspcircuit implements CSProcess{ private Matrix costmat; public tspcircuit(Matrix costmat){ this. costmat = costmat; } public void run(){ int num. R = costmat. num. Rows(); One 2 One. Channel Masterto. Row[] Rowto. Master[] Up[] Down[] for(int r = 0; r Masterto. Row[r] Rowto. Master[r] Up[r] Down[r] } < = = = = new new One 2 One. Channel[num. R]; num. R; r++){ new One 2 One. Channel();

TSPRow. Solver rowsolvers[] = new TSPRow. Solver[num. R]; for(int r = 0; r < TSPRow. Solver rowsolvers[] = new TSPRow. Solver[num. R]; for(int r = 0; r < num. R; r++) rowsolvers[r] = new TSPRow. Solver (r, Masterto. Row[r], Down[r], Up[(r + 1) % num. R], Rowto. Master[r], Up[r], Down[(r + 1) % num. R]); new Parallel(new CSProcess[]{ new tsp. Master(costmat, Masterto. Row, Rowto. Master), new Parallel(rowsolvers) }). run(); }}

class TSPRow. Solver extends My. Object implements CSProcess{ private Channel. Input from. Master; private class TSPRow. Solver extends My. Object implements CSProcess{ private Channel. Input from. Master; private Process. Read read. Above = null; private Process. Read read. Below = null; private Channel. Output to. Master; private Channel. Output to. Above; private Channel. Output to. Below; private int my. Row; public TSPRow. Solver(int row, Channel. Input from. Master, Channel. Input from. Above, Channel. Input from. Below, Channel. Output to. Master, Channel. Output to. Above, Channel. Output to. Below){ my. Row = row; this. from. Master = from. Master; read. Above = new Process. Read(from. Above); read. Below = new Process. Read(from. Below); this. to. Master = to. Master; this. to. Above = to. Above; this. to. Below = to. Below; }

public void run(){ int costrow[] = null; costrow int totrow[] int dirrow[] = (int[]) public void run(){ int costrow[] = null; costrow int totrow[] int dirrow[] = (int[]) from. Master. read(); = new int[costrow. length]; int num. C = costrow. length; int up. Val, dn. Val, row. Val; int col = num. C - 1; totrow[col] = costrow[col]; dirrow[col] = 0;

for(col = col - 1; col >= 0; col--){ row. Val = costrow[col+1]; new for(col = col - 1; col >= 0; col--){ row. Val = costrow[col+1]; new Parallel(new CSProcess[]{ new Proc. Write(to. Above, new Integer(totrow[col+1])), new Proc. Write(to. Below, new Integer(totrow[col+1])), read. Above, read. Below }). run(); row. Val = totrow[col+1]; up. Val = ((Integer)read. Above. value). int. Value(); dn. Val = ((Integer)read. Below. value). int. Value(); // computation for one entry } } System. out. println("Rowsolver " + my. Row + " done. "); to. Master. write(totrow); to. Master. write(dirrow); } }

class tsp. Master extends My. Object implements CSProcess{ private Process. Write writeto. Row[] = class tsp. Master extends My. Object implements CSProcess{ private Process. Write writeto. Row[] = null; private Process. Read readfrom. Row[] = null; private Matrix costmat = null; private Matrix totmat = null; private Matrix dirmat = null; private int num. R; public tsp. Master(Matrix costmat, Channel. Output[] to. Row, Channel. Input[] from. Row){ this. costmat = costmat; num. R = costmat. num. Rows(); writeto. Row = new Process. Write[num. R]; readfrom. Row = new Process. Read[num. R]; for(int r = 0; r < num. R; r++){ writeto. Row[r] = new Process. Write(to. Row[r]); readfrom. Row[r] = new Process. Read(from. Row[r]); } }

public void run(){ totmat = new Matrix(num. R, costmat. num. Cols()); dirmat = new public void run(){ totmat = new Matrix(num. R, costmat. num. Cols()); dirmat = new Matrix(num. R, costmat. num. Cols()); for(int r = 0; r < num. R; r++) writeto. Row[r]. value = costmat. row(r); new Parallel(writeto. Row). run(); new Parallel(readfrom. Row). run(); for(int r = 0; r < num. R; r++) totmat. set. Row(r, (int[])readfrom. Row[r]. value); new Parallel(readfrom. Row). run(); for(int r = 0; r < num. R; r++) dirmat. set. Row(r, (int[])readfrom. Row[r]. value); // Print out results }

JCSP Selection Selects a channel ready for reading from an array of channels Implies JCSP Selection Selects a channel ready for reading from an array of channels Implies non-determinism Declare an Alternative object – select function returns index of ready channel – variations allow » boolean array, channel can be selected only if boolean is true » timer -- select continues after specified time » skip -- select continues immediately if no channel is ready

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

“Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P “Wot, No Chickens!” Library Canteen P 0 P 1 P 2 P 3 P 4 A L T ALT Cooking Chef

class Server implements CSProcess{ private Alting. Channel. Input. Int in[] private Channel. Output. Int class Server implements CSProcess{ private Alting. Channel. Input. Int in[] private Channel. Output. Int out[] private Channel. Output. Int to. Service private Channel. Input. Int from. Service = = null; public Server(Alting. Channel. Input. Int in[], Channel. Output. Int out[], Channel. Output. Int to. Service, Channel. Input. Int from. Service){ this. in = in; this. out = out; this. to. Service = to. Service; this. from. Service = from. Service; }

public void run(){ // Server Alternative alt = new Alternative(in); int index; while(true){ index public void run(){ // Server Alternative alt = new Alternative(in); int index; while(true){ index = alt. fair. Select(); in[index]. read(); to. Service. write(0); from. Service. read(); out[index]. write(1); } } }

class Service extends My. Object implements CSProcess{ private Alting. Channel. Input. Int in[] = class Service extends My. Object implements CSProcess{ private Alting. Channel. Input. Int in[] = new Alting. Channel. Input. Int[2]; private Channel. Output. Int to. Server; public Service(Alting. Channel. Input. Int from. Chef, Alting. Channel. Input. Int from. Server, Channel. Output. Int to. Server){ this. in[0] = from. Chef; this. in[1] = from. Server; this. to. Server = to. Server; }

public void run(){ // Service int num. Chicks = 0; int index; boolean ready[] public void run(){ // Service int num. Chicks = 0; int index; boolean ready[] = new boolean[2]; Alternative alt = new Alternative(in); ready[0] = true; while(true){ ready[1] = (num. Chicks > 0); index = alt. select(ready); if(index == 0){ num. Chicks = in[0]. read(); nap(3000); in[0]. read(); } else{ in[1]. read(); num. Chicks--; to. Server. write(1); } }

class Canteen extends My. Object implements CSProcess{ private Alting. Channel. Input. Int from. Phil[] class Canteen extends My. Object implements CSProcess{ private Alting. Channel. Input. Int from. Phil[] = null; private Channel. Output. Int to. Phil[] = null; private Alting. Channel. Input. Int from. Chef = null; public Canteen(Alting. Channel. Input. Int from. Phil[], Channel. Output. Int to. Phil[], Alting. Channel. Input. Int from. Chef){ this. from. Phil = from. Phil; this. to. Phil = to. Phil; this. from. Chef = from. Chef; }

public void run(){ // Canteen One 2 One. Channel. Int Serverto. Service = new public void run(){ // Canteen One 2 One. Channel. Int Serverto. Service = new One 2 One. Channel. Int(); One 2 One. Channel. Int Serviceto. Server = new One 2 One. Channel. Int(); new Parallel( new CSProcess[]{ new Server(from. Phil, to. Phil, Serverto. Service, Serviceto. Server), new Service(from. Chef, Serverto. Service, Serviceto. Server) }). run(); }

class Chef extends My. Object implements CSProcess{ private Channel. Output. Int to. Canteen = class Chef extends My. Object implements CSProcess{ private Channel. Output. Int to. Canteen = null; public Chef(Channel. Output. Int to. Canteen){ this. to. Canteen = to. Canteen; } public void run(){ int num. Chicks = 4; while(true){ nap(2000); // Cooking to. Canteen. write(num. Chicks); // Delivering to. Canteen. write(0); // 4 chickens up } } }

class Phil extends My. Object implements CSProcess{ private int id; private Channel. Output. Int class Phil extends My. Object implements CSProcess{ private int id; private Channel. Output. Int to. Canteen = null; private Channel. Input. Int from. Canteen = null; public Phil (int id, Channel. Output. Int to. Canteen, Channel. Input. Int from. Canteen) { this. id = id; this. to. Canteen = to. Canteen; this. from. Canteen = from. Canteen; }

public void run () { int chicken; // Phil while (true) { if (id public void run () { int chicken; // Phil while (true) { if (id > 0) { nap(3000); // } to. Canteen. write(id); // chicken = from. Canteen. read(); // } } Thinking Gotta Eat Mmmm. . . that's good

class College. Circuit implements CSProcess{ public void run(){ One 2 One. Channel. Int Philto. class College. Circuit implements CSProcess{ public void run(){ One 2 One. Channel. Int Philto. Canteen[] = new One 2 One. Channel. Int[5]; One 2 One. Channel. Int Canteento. Phil[] = new One 2 One. Channel. Int[5]; One 2 One. Channel. Int Chefto. Canteen = new ONe 2 One. Channel. Int; Phil phillist[] = new Phil[5]; for(int k = 0; k < 5; k++){ Philto. Canteen[k] = new One 2 One. Channel. Int(); Canteento. Phil[k] = new One 2 One. Channel. Int(); } for(int k = 0; k < 5; k++) phillist[k] = new Phil(k, Philto. Canteen[k], Canteento. Phil[k]); new Parallel( new CSProcess[]{ new Parallel(phillist), new Chef(Chefto. Canteen), new Canteen(Philto. Canteen, Canteento. Phil, Chefto. Canteen) }). run(); } }

CSP, Theory Processes Events (Communications) – read from channel – write to channel Rules CSP, Theory Processes Events (Communications) – read from channel – write to channel Rules of Composition – Parallel – Choice – Non-deterministic Selection

CSP Provides an algebraic structure for analysis – a process algebra Enables us to CSP Provides an algebraic structure for analysis – a process algebra Enables us to reason about concurrent systems – prove that a system is deadlock-free – define a denotational semantics for CSP Tools for automated analysis are available – FDR (Failures/Divergences Refinement