$BJB9T%7%9%F%`(B $B%7%9%F%`>pJs7O(B/$B>pJs9)3X0h(B, $B%7%9%F%`>pJs9)3X8&5f72(B/$B>pJsM}9)3X0L%W%m%0%i%`(B $B%7%9%F%`>pJs9)3X8&5f2J(B/$B%3%s%T%e!<%?%5%$%(%s%9@l96(B $B?7>k(B $BLw(B <yas@cs.tsukuba.ac.jp>
$B$3$N%Z!<%8$O!"
http://www.cs.tsukuba.ac.jp/~yas/cs/csys-2023/2023-06-09
$B$"$k$$$O!"
http://www.cs.tsukuba.ac.jp/~yas/cs/
http://www.cs.tsukuba.ac.jp/~yas/
$B;29MJ88%(B References
Per Brinch Hansen$BCx(B, $BEDCf1QI'Lu(B: "$BJB9TF0:n%W%m%0%i%`$N9=B$(B", $BF|K\%3%s(B $B%T%e!<%?6(2q(B (1980).
Per Brinch Hansen: "The programming language Concurrent Pascal," IEEE Transactions on Software Engineering, Vol.SE-1, No.2, pp.199-207, June 1975.
type procA_t = process(args...); var local variables... procedure proc1(args...); procedure proc2(args...); begin cycle ... end; end var procA1 : procA_t ; init procA1(args...);
type monA_t = monitor(args $B!&!&!&(B); var loal variables procedure entry proc1(args $B!&!&!&(B); procedure entry proc2(args $B!&!&!&(B); begin initialization of local variables; end var monA1 : monA_t ; init monA1($B0z?t(B);$B%m!<%+%kJQ?t$O!"(Bentry $B$N
$B?^(B? Concurrent Pascal$B$N%W%m%;%9$H%b%K%?(B/Processes and a monitor in Concurrent Pascal
cv1 : condition; cv1.wait; $B8F$S=P$7$?%W%m%;%9$rBT$?$;$k!#(Bblock the current process. cv1.signal; $BBT$C$F$$$k%W%m%;%9$,$$$l$PA4$F:F3+$5$;$k!#(Bunblock all waiting processes.
q1 : queue; delay(q1); $B8F$S=P$7$?%W%m%;%9$r$=$N%-%e!<$GBT$?$;$k!#(B block the current process. continue(q1); $B$=$N%-%e!<$GBT$C$F$$$k%W%m%;%9$,$$$l$P#1$D$@$1:F3+$5$;$k!#(B unblock a single process in the queue.
$B?^(B? $BM-8B%P%C%U%!(B($B4D>u%P%C%U%!(B)$B!"@8;:CHq
$B%P%C%U%!$,6u$N;~!"(Bconsumer() $B$O!"(Bproducer() $B$,2?$+%G!<%?$r%P%C(B
$B%U%!$KF~$l$k$N$rBT$D!#%P%C%U%!$,$$$C$Q$$$N;~!"(Bproducer() $B$O!"(B
consumer() $B$,%P%C%U%!$+$i2?$+%G!<%?$r
$B
$B652J=q(B
C. A. R. Hoare: "Communicating Sequential Processes",
Prentice-hall International, 1985.
[PDF(2015)]
Process A:
1: const BUFFER_SIZE = 4;
2: type circular_buffer =
3: monitor
4: var
5: rp : integer ;
6: wp : integer ;
7: data: array [0..BUFFER_SIZE-1] of integer;
8: used: integer;
9: not_empty : condition;
10: not_full : condition;
11:
12: procedure entry put(x:integer);
13: begin
14: while( used = BUFFER_SIZE ) do
15: non_full.wait;
16: data[wp] := x;
17: wp := wp + 1 ;
18: if( wp >= BUFFER_SIZE )
19: wp := 0 ;
20: used := used + 1 ;
21: not_empty.signal;
22: end
23:
24: procedure entry get(result x:integer);
25: begin
26: while( used = 0 ) then
27: not_empty.wait;
28: x := data[rp];
29: rp := rp + 1 ;
30: if( rp >= BUFFER_SIZE )
31: rp := 0 ;
32: used := used - 1 ;
33: not_full.signal;
34: end
35: begin
36: rp := 0 ;
37: wp := 0 ;
38: used := 0 ;
39: end;
40:
41: ...
42: var buf : circular_buffer ;
43: init buf;
44: ...
45:
$B"#(BCommunicating Sequential Processes
C. A. R. Hoare: "Communicating sequential processes", Communications
of the ACM, Volume 21 , No.8 pp.666-677, 1978.
https://dl.acm.org/citation.cfm?doid=359576.359585
$B"!(BCSP$B$NDL?.$H%W%m%;%9(B/Communication and processes in CSP
$BD>@\L>A0IU$1$NDL?.(B(direct naming)$B!#DL?.Aj
...
B ? x; -- $B%W%m%;%9(B B $B$+$i$NDL?.$rBT$D!#(B Wait for a message from Process B.
-- $B%a%C%;!<%8$r
Process B:
... y := 5; A ! y + 1; -- $B%W%m%;%9(B A $B$XCM(B 6 $B$rAw$k!#(BSend the value 6 to Process A. ... A ? y; -- $B%W%m%;%9(B A $B$+$i$NDL?.$rBT$D!#(BWait for a message from Process A. -- $B%a%C%;!<%8$r$B%W%m%;%9$r;XDj$9$kL>A0IU$1$G$O!"%i%$%V%i%j$,:n$l$J$$!#%^%/%m$G$4$^$+$9!#(B
$B"!@)8f9=B$!"%,!<%IIU$-%3%^%s%I!"Hs7hDj@-(B
$BL>A0(B::...
||
$B""(B
$B!!(B($B@5J}7A$G$O$J$/!"=DD9$K=q$/$N$,@53N!#!V(B▯ $B!W$N$h$&$J46$8!#(B)
$B?^(B? CSP$B$K$h$k%^!<%8!&%W%m%;%9(B/A merge process in CSP
$B$b$7Hs7hDj@-$,$J$1$l$P!"I,$:(B X, Y, Z, X, Y, Z, ... $B$H7+$jJV$9!#(BMerge:: c:character; *[ X ? c $B"*(B Sink ! c; Y ? c $B"*(B Sink ! c; Z ? c $B"*(B Sink ! c ]
1: [ Buffer:: 2: buf(0..bufsize-1): buffer_element; 3: first, last : integer; 4: j,k : integer; 5: first :=0; 6: last :=0; 7: * [ (j: 1..numprod) 8: (last + 1) mod bufsize $B!b(B first; 9: Producer(j) ? buf(last) $B"*(B 10: last := (last +1) mod bufsize 11: $B""(B 12: (k: 1..numcons) 13: first $B!b(B last; 14: Consumer(k) ? more() $B"*(B 15: Consumer(k) ! buf(first); 16: first := (first + 1) mod bufsize 17: ] 18: || (i:1..numprod) PRODUCER -- $B@8;:CHq
- $B%W%m%;%9(B Buffer $B$O!"(BProducer $B$+$i%G!<%?$r $B%W%m%;%9(B Buffer $B$O!"(BConsumer $B$+$i(B more() $B$H$$$&%a%C%;!<%8$r(B $B
$B"!(BOccam
Occam $B$O!"(BInmos $B$B"!(Breferees CSP $B$OM}O@E*$J8!>Z$K6/$$!#(B ($B%^%k%A%9%l%C%I$G$O$H$F$b8!>Z$O$G$-$J$$!#(B) $BB>$N8@8l$G(B CSP $B$N9M$(J}$r;H$&!#(B $B8&5f2q(B
https://www.cs.kent.ac.uk/projects/ofa/jcsp/,Communicating Sequential Processes for Java
https://www.cs.kent.ac.uk/projects/ofa/c++csp/,C++CSP2
https://www.cs.kent.ac.uk/projects/ofa/nocc/,NOCC: a new occam-pi compiler
https://github.com/futurecore/python-csp,Python-CSP
http://www.cs.uit.no/~johnm/code/PyCSP/,PyCSP
http://wotug.org/,World Transputer User Group (WoTUG)
http://www.csp-consortium.org/,CSP $B%3%s%=!<%7%"%`(B($BF|K\(B)
$B"#(BAda
- $BJF9q9qKI>J(B(Department of Defense (DoD))$B$,7hDj$7$?AH$_9~$_%7%9%F%`(B(embedded systems)$B$r5-=R$9$k$?$a$N8@8l!#(B
- $BNc30=hM}(B(exceptions)$B!"J?9T=hM}(B(concurrent processing)$B!" Pascal $BIw$NJ8K!!#(BPascal-like syntax.
- ACM SIGPLAN Notices $B;o$G!";f>eF$O@!#(B
$B"!%?%9%/(B/Tasks
$BJB9T$KF0:n$9$k%*%V%8%'%/%H(B($B8=:_$NMQ8l$G$O%9%l%C%I(B(thread))$B$r- task$B7?$N%$%s%9%?%s%9$r@8@.$G$-$k!#(B
- $B6I=jJQ?t$H6I=j
$B@8@.$5$l$k$H!" $B%W%m%0%i%`$N=*$o$j$KMh$k$H=*N;!#L@<(E*$K=*N;$5$;$i$l$k!#%(%i!<$G(B $B0[>o=*N;$9$k$3$H$,$"$k!#(B - $B%?%9%/$NCf$K%?%9%/$,=q$1$k!#(B
- $B:F5"8F=P$7$b2DG=!#:F5"$G0EL[E*$K%?%9%/$,@8@.$5$l$k$3$H$,$"$k!#(B
$B"!;EMM$HK\BN(B/specification and body
Ada$B$O!"%+%W%;%k2=$r=E;k$7$?@_7W$K$J$C$F$$$k!#(B
- $B;EMM(B(specification)
- $B%$%s%?%U%'!<%9$N5-=R(B(interface description)$B!#%W%m%0%i%`$NB>$NMWAG(B $B$+$i;2>H$G$-$k!#;EMM$@$1$o$+$l$P!"J,3d%3%s%Q%$%k$G$-$k!#(B
- $BK\BN(B(body)
- $B%W%m%0%i%`$N%3!<%I!"JQ?t$J$I!#(B
$B"!%(%s%H%j(B/entries
$B%W%m%;%94VDL?.!J%?%9%/4VDL?.!K$Nl=j$K(Baccept $BJ8$r5-=R$9$k!#(B$B;EMM$NNc!##19T$N%P%C%U%!!#(B
task line_block is entry add( c: in character); end line_block;in $B$O!"F~NO%Q%i%a%?$N0UL#!#%?%9%/B&$+$i8+$FF~NO!J$B accept add( c: in character) do thisline(i) := c; end add; // i := i + 1;
$B8F=P$7B&$NNc(B
line_block.add("d");$B%(%s%H%j$r8F$S=P$9$H!"8F$S=P$7$?%?%9%/$O!"%V%m%C%/$5$l$k!#(B $B$B"!%i%s%G%V(B/Rendezvous
$B?^(B? $BBP>NE*$J%i%s%G%V(B/ Symmetric rendezvous
$B?^(B? Ada$B$N%i%s%G%V(B/ Rendezvous in Ada
select when Cond => accept ... do ... end; or when Cond => accept ... do ... end; or when Cond => delay seconds; end
when Cond =>
$B!W$O!"=q$+$J$/$F$b$h$$!#(B
1: type line is array (1..120) of character; 2: 3: task line_block is 4: entry add( c: in character); 5: entry please_print( ln: out line); 6: end line_block; 7: 8: task body line_block is 9: printer_trouble_time : constant integer := 300; 10: print_line, fill_line : line; 11: nextfree : integer; 12: print_ready : boolean; 13: begin 14: nextfree := 1; 15: print_ready := false; 16: loop 17: select 18: when (nextfree < 121 ) => 19: accept add( c: in character) do 20: fill_line(nextfree) := c; 21: end add; 22: nextfree := nextfree + 1; 23: if( next_free = 121 ) and not print_ready then 24: print_ready := true; 25: nextfree := 1; 26: print_line := fill_line; 27: end if; 28: or 29: when print_ready => 30: accept please_print( ln: out line ) do 31: ln := print_line; 32: end please_print; 33: if nextfree = 121 then 34: print_line := fill_line; 35: nextfree := 1; 36: else 37: print_ready := false; 38: end if; 39: or 40: when print_ready and (nextfree > 120) => 41: delay printr_trouble_time; 42: printer_trouble; 43: end select; 44: end loop; 45: end line_block;
$B%W%m%0%i%_%s%08@8l$O!"%M%C%H%o!<%/$NB8:_$dDL?.$r$5$^$6$^$JEY9g$$$G1#$7$F$$$k!#(B A programming language hides underlying networks and communication in a degree.
$BLdBj(B Question:
$B%M%C%H%o!<%/$N5!G=$O$"$k!#(Bhas a networking facility.
$BMxMQ
$B%3%^%s%I(B commands
$BJ,;67?%*%Z%l!<%F%#%s%0!&%7%9%F%`(B a distributed operating system
$BMxMQ
$BL\I8(B goals
$BCm0U(B: $BIi2YJ,;6$NJ,;6(B(load sharing/balancing)$B$H$3$N9V5A$N%?%$%H%k$NJ,;6(B (distributed)$B$O0UL#$,0c$&!#(B
A note on Distributed Computing [Waldo 1994]
$BNc(B:
$BJ,;6$NFq$7$$LdBj$O!"$^$@HFMQE*$K2r$1$k5;=Q$O$J$$!#(B $BHFMQ@-$,$J$$$H!"%W%m%0%i%_%s%08@8l$K$O:N$jF~$l$K$/$$!#(B
$B0lHLE*$JFCD'(B
Emerald $B$NL\I8!#(B
$B%a%=%C%I8F=P$7$N0z?t$b;2>H$GEO$5$l$k!#%*%V%8%'%/%H$N>l=j$,0c$&$H!"=E$?(B $B$$!#%3%T!<$NJ}$,B.$$!#(B
Call by reference $B$,=E$?$$!#(B
http://www.recursionsw.com/products/voyager/voyager-intro.html
import com.objectspace.voyager.*; public interface IBall { public void hit(); }
import com.objectspace.voyager.*; public class Ball implements IBall { public void hit() { System.out.println("Ball has been hit"); } }
import com.objectspace.voyager.*; public class BallMachine { public static void main(String[] args) { try { Voyager.startup("8000"); // als Server starten Ball ball = new Ball(); Namespace.bind("EinBall",ball); } catch( Exception exception ) { System.err.println( exception ); } } }
import com.objectspace.voyager.*; public class Bat { public void play(IBall ball) { System.out.println("Hitting the new Ball"); ball.hit(); } public static void main(String[] args) { try { Voyager.startup(); // als Client starten Bat bat = new Bat(); IBall ball = (IBall) Namespace.lookup("//vsyspc5.informatik.uni-hamburg.de:8000/EinBall"); bat.play(ball); } catch( Exception exception ) { System.err.println( exception ); } Voyager.shutdown(); } }
IMobility mobileObj = Momility.of(obj); mobileObj.moveTo("url");
import com.objectspace.voyager.*; import com.objectspace.voyager.mobility.*; public class Bat { public void play(IBall ball, String url) { try { ball.hit(); System.out.println("Ball bewegen?"); Mobility.of(ball).moveTo(url); System.out.println("Ball bewegt"); } catch (MobilityException e) { System.out.println(e); e.printStackTrace(); } } public static void main(String[] args) { try { Voyager.startup("9001"); ClassManager.enableResourceServer(); Bat bat = new Bat(); //Ball newball= new Ball(); IBall ball = (IBall) Proxy.of(new Ball()); bat.play(ball,"//vsyspc5:8000"); System.out.println("Ball 1ste mal gespielt"); bat.play(ball,"//localhost:9001"); } catch( Exception exception ) { System.err.println( exception ); } Voyager.shutdown(); } }
IA a1 = (IA) Factory.create("A","//sun:8000");
IA a1 = (IA) Factory.create("A","//sun:8000"); int x = a1.method(param1,param2); // $BF14|(B synchronous
Result r1 = Future.invoke(a1, "method", // $BHsF14|(B asynchronous new Object [] {param1,param2}); ... if( r1.isAvailable() ) { int x = r1.readInt(); }$B%a%=%C%IL>$rJ8;zNs$GEO$9!#7k2L$H$7$F!"(BResult $B7?$rJV$9!#(BisAvailable() $B%a%=%C%I$G=*N;$rBT$D!#(BreadInt(), readByte(), readObject() $B$G!"(Bint, byte, $B%*%V%8%'%/%H$KLa$9!#(B
A a1 = new A(); A a2 = new A(); a1.method1( param1, param2 ); // Unicast a2.method1( param1, param2 ); // Unicast ISubspace subspace = (ISubspace) Namespace.lookup("//sun:9000/Subspace"); subspace.add(a1); subspace.add(a2); Object [] params = new Object [] { param1, param2 }; Multicast.invoke(subspace,"method1",params,"A");
public class Hello implements java.io.Serializable { public void sayHello(java.lang.String name) { System.out.println("Hello " + name); } }djayc $B%3%s%Q%$%i$G!"#2$D$N(B Java $B$N%/%i%9$,:n$i$l$k!#(B The djayc compiler generates two Java class files.
import dejay.base.*; public class HelloStartup { public static void main(String args[]) { try { DjProcessor p1 = new DjProcessor("//localhost:8000"); DjHello hello1 = new DjHello(p1); hello1.sayHello("Thorsten"); p1.moveTo("//localhost:9000"); hello1.sayHello("Jan"); hello1.moveTo("//mac:9000"); } catch (ConstructProcessorFailedException e) { System.out.println("Creating Virtual Processor failed."+e); } } }
DjProcessor p1 = new DjProcessor("hostname:port");$B$3$l$K$h$j!"%[%9%H(B
hostname
$B>e$N(B
$B%]!<%HHV9f(B port
$B$G?7$?$J(B
$B2>A[%W%m%;%C%5$,:n$i$l$k!#(B
$B%[%9%H(B hostname
$B$G$O!";vA0$K(B
Voyager $B%G!<%b%s$rAv$i$;$F$*$/I,MW$,$"$k!#(B
class A
(.dj) $B$+$i!"<+F0E*$K(B
$B%9%?%V(B($B%W%m%-%7(B)$B$H$J$k(B
class DjA
$B$,@8@.$5$l$k!#(B
$B%3%s%9%H%i%/%?$N0z?t$,#18DB?$$!#(B
DjA a1 = new DjA( A$B$N0z?t!&!&!&(B, DjProcessor );$B$3$l$G!"1s3V$N2>A[%W%m%;%C%5$G%*%V%8%'%/%H$,@8@.$5$l!"(B $B1s3V;2>H(B(remote reference)$B$,JV$5$l$k!#(B $BDL>o$N;2>H$HF1$8$K$J$k$h$&$K4hD%$C$F$$$k$,!"(B $B0lIt0c$&!#(B
DjA a2 ; a2 = ... ; ... if( a2 == a1 ) // $B1s3V$N%*%V%8%'%/%H$G$O$J$/$F%m!<%+%k$N%9%?%V$NHf3S(B { ... }equals() $B%a%=%C%I$O!"1s3V$G$bF/$/!#(B
$B%m!<%+%k!&%*%V%8%'%/%H$r0z?t$K$7$F!"(B $B%j%b!<%H!&%*%V%8%'%/%H$r8F$V$H!"<+F0E*$K1s3V$K%3%T!<$,EO$5$l$k!#(B $B!J1s3V%*%V%8%'%/%H$,:n$i$l$F!"1s3V;2>H$,EO$5$l$k$N$G$O$J$$!#!K(B
DjX
$B7?$N%*%V%8%'%/%H$r(B
$B1s3V$K%j%?!<%s$9$k$3$H$O$G$-$k!#(B
DjX
$B$,$_$D$+$i$J$1$l$P!"(B
X
$B$N%3%T!<$,JV$5$l$k!#(B
remote.getCopy() $B$G!"%m!<%+%k$N%3%T!<$,F@$i$l$k!#(B
DjA a1 = new DjA(p1); A a2 = a1.getCopy();
DjA a1 = new DjA(p1); B b1 = a1.method1( 10 ); // $BF14|!!(B synchronous B b2 = a1.method1( 10, Dejay.ASYNC ); // $BHsF14|(B asynchronous a1.method1( 10, Dejay.ONEWAY ); // $B0lJ}8~(B one-way$BHsF14|$K$O!"40N;BT$A$NJ}K!$,#2
B b2 = a1.method1( 10, Dejay.ASYNC ); if( b2.isAvailable() ) { b2.method2(); } else { // do something b2.waitForResult(); b2.method2(); }
$B#2%l%Y%k$NL>A0!#(B
DjProcessor p1 = new DjProcessor("lin:8000"); p1.registerByName("p1"); DjA a1 = new DjA(p1); a1.registerByName("a1");
DjProcessor p1 = Dejay.getProcessorByName("p1"); DjA a1 = p1.getObjectByName("a1");
persist() $B$G%G!<%?%Y!<%9$KJ]B8$5$l$?%*%V%8%'%/%H$b!"(B $B;H$o$l$k<+F0E*$K%G!<%?%Y!<%9$+$i2sI|$5$l$k!#(B
$B2>A[%W%m%;%C%5A4BN$,%G!<%?%Y!<%9$KJ]B8$G$-$k!#(B $B DjProcessor p1 = Dejay.getProcessorFromDB("PersistProc", "ProcesssorDB","lin:8000");
X:: Merge ! "x1"; Merge ! "x2"; Y:: Merge ! "y1"; Z:: Merge ! "z1";$B$3$N;~!"(BSink $B%W%m%;%9$,
Choose one *important* similarity for describing concurrent systems in Concurrent Pascal and Ada. Describe this similarity briefly.
Glue, which realizes XML Web services (with WSDL), and Java Remote Method Invocation (RMI) provide Remote Procedure Call (RPC). Choose an important advantage of Voyager over Glue and Java RMI. Describe this advantage briefly.
Dejay has an advantage over Voyager that it has compiler support. Describe an example of the compiler support. Compare the description in Voyager and the that in Dejay.