$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-2020/2020-06-26
$B$"$k$$$O!"
http://www.cs.tsukuba.ac.jp/~yas/cs/
http://www.cs.tsukuba.ac.jp/~yas/
$B;29MJ88%(B References
$B8@8l$H$7$F$O!"2?
$B8=:_$G$O!"%"%/%?$r!V(B($BJB9T(B)$B%*%V%8%'%/%H!W$HFI$_BX$($k$HJ,$+$j$d$9$$!#(B
$B?^(B? $B%"%/%?$N4pK\35G0(B/Basic concepts of the Actor model
$B%"%/%?$O!"%a%C%;!<%8$r
$B%"%/%?$,%a%C%;!<%8$r
$BMWAG(B
$B%"%/%?$O!"%a%C%;!<%8$rAw$B"!7QB3(B/Continuations
$B7QB3(B(continuation$B!"7QB3E@$H$b$$$&(B)$B$rMQ$$$k!#(B
$B5f6K$N(B goto $BJ8!#(BC $B8@8l$N4X?t$G(B
goto f(1, 2, 3);
$B$N$h$&$J$b$N!#(B
$BDL>o$N3,>h(B(in Scheme)
(define (fact n) (if (= n 0) 1 (* n (fact (- n 1)))))$B7QB3$r
(define (fact-c n c) (if (= n 0) (c 1) (let ((c2 (lambda (x) (c (* n x))))) (fact-c (- n 1) c2))))
$B
6
> (fact 4)
24
> (fact-c 3 print)
6> (fact-c 4 print)
24>
factorial$B-q&K(Bm. match m <n c> if n = 1 then (send c <1>) else if n > 1 then (send factorial <(n-1) ($B&K(Bk.(send c <n * k>))>)3$B$N3,>h$r7W;;$7$F!"7QB3(Bprint_answer$B$KAw$j$?$$;~$K$O!"(B $B (send factorial <3 print_answer>)
(define (Factorial( )) (Is-Communication (a doit (with customer =m) (with number =n)) do (become Factorial) (if (NOT (= n 0)) (then (send m 1)) (else (let (x = (new FactCust (with customer m) (with number n))) (send Factorial (a do (with customer x) (with number (- n 1))))))))) (define (FactCust (with customer =m) (with number =n)) (Is-Communicaton (a number k) do (send m (* n k))))
$B?6$kIq$$5-=R(B (define ($BL>A0(B (with id $B%Q%?%s(B)) $BDL?.%O%s%I%i$NJB$S(B) $BDL?.%O%s%I%i(B (Is-Communication $B%Q%?%s(B do $B%3%^%s%I(B) let$B%3%^%s%I(B (let ($BJQ?tL>(B = $B<0(B) do $B%3%^%s%I(B) $B>r7o%3%^%s%I(B (if $B<0(B (then do $B%3%^%s%I$NJB$S(B) (else do $B%3%^%s%I$NJB$S(B)) $B%a%C%;!<%8Aw?.%3%^%s%I(B (send $B%a!<%k%\%C%/%9(B $BCM(B) becom$B%3%^%s%I(B (become $B<0(B) $B?7$7$$%"%/%?$N@8@.(B (new $B<0(B)
(define (Account (with Balance =b)) (Is-Request (a Balance) do (become (Account (with Balance b))) (reply b)) (Is-Request (a Deposit (with Amount =a)) do (become (Account (with Balance (+ b a)))) (reply (a Deposit-Receipt (with Amount a)))) (Is-Request (a Withdrawal (with Amount =a)) do (if (> a b) (then do (become (Account (with Balnce b))) (complain (an Overdraft))) (else do (become (Account (with Balnce(- b a)))) (reply (a Withdrawal-Receipt (with Amount a)))))))
https://www.ibm.com/developerworks/jp/java/library/j-scala04109.html
Ted Neward: "The busy Java developer's guide to Scala: Dive
deeper into Scala concurrency", IBM DeveloperWorks, 10 Apr 2009.
https://www.ibm.com/developerworks/java/library/j-scala04109.html
$B%j%9%H(B 9. Counter $B$NNc(B ($B%"%/%?!<$K$h$kJ}K!(B) $B$h$j!#(B
object CountingSample { case class Incr case class Value(sender : Actor) case class Lock(sender : Actor) case class UnLock(value : Int) class Counter extends Actor { override def act(): Unit = loop(0) def loop(value: int): Unit = { receive { case Incr() => loop(value + 1) case Value(a) => a ! value; loop(value) case Lock(a) => a ! value receive { case UnLock(v) => loop(v) } case _ => loop(value) } } } def main(args : Array[String]) : Unit = { val counter = new Counter counter.start() counter ! Incr() counter ! Incr() counter ! Incr() counter ! Value(self) receive { case cvalue => Console.println(cvalue) } counter ! Incr() counter ! Incr() counter ! Value(self) receive { case cvalue => Console.println(cvalue) } } }
// This function launches a new counter actor fun CoroutineScope.counterActor() = actor<CounterMsg> { var counter = 0 // actor state for (msg in channel) { // iterate over incoming messages when (msg) { is IncCounter -> counter++ is GetCounter -> msg.response.complete(counter) } } }
fun main() = runBlocking { val counter = counterActor() // create the actor withContext(Dispatchers.Default) { massiveRun { counter.send(IncCounter) } } // send a message to get a counter value from an actor val response = CompletableDeferred<Int>() counter.send(GetCounter(response)) println("Counter = ${response.await()}") counter.close() // shutdown the actor }
a = actor {...}
$B$G!"%"%/%?@8@.!#L58B%k!<%W4^$`!#(B
-module(counter). -export([run/0, counter/1]). run() -> S = spawn(counter, counter, [0]), send_msgs(S, 100000), S. counter(Sum) -> receive value -> io:fwrite("Value is ~w~n", [Sum]); {inc, Amount} -> counter(Sum+Amount) end. send_msgs(_, 0) -> true; send_msgs(S, Count) -> S ! {inc, 1}, send_msgs(S, Count-1). % Usage: % 1> c(counter). % 2> S = counter:run(). % ... Wait a bit until all children have run ... % 3> S ! value. % Value is 100000
$B#13,=R8lO@M}$NO@M}<0$O!"
P 1 $B"K(B P 2 $B"K(B ... $B"K(B P n $B"+(B Q 1 $B"J(B Q 2 $B"J(B ... $B"J(B Q n.
$B!V"+!W$N:8$,$?$+$@$+(B1$B8D$N$b$N$,%[!<%s@a(B(Horn clause)$B!#(B(OR$B$,J#?t=q$-$?$/(B
$B$J$C$?$i!"J#?t9T$K$o$?$C$F=q$/(B)$B!#%[!<%s@a$K$O(B3$B $B?^(B? Prolog $B$N(B append $B?^(B? Prolog $B$K$h$k%/%$%C%/%=!<%H(B
H :- G 1, G 2,...,G n | B 1, B 2, ..., B m.
$B"!C1=c$J%b%G%k(B($B;v
fatherof(isaac,abraham). -- isaac $B$NIc$O(B abraham $B$G$"$k(B
fatherof(ishmail,abraham).
fatherof(shuah,abraham).
fatherof(jacob,isaac).
fatherof(esau,isaac).
fatherof(reuben,jacob).
fatherof(dinah,jacob).
fatherof(dan,jacob).
fatherof(asher,jacob).
fatherof(joseph,jacob).
motherof(isaac,sarah). -- isaac $B$NJl$O(B sarah $B$G$"$k!#(B
motherof(ishmail,hagar).
motherof(shuah,ketura).
motherof(jacob,rebeccah).
motherof(easu,rebeccah).
motherof(reuben,leah).
motherof(dinah,leah).
motherof(dan,bilhah).
motherof(asher,zilpah).
motherof(joseph,rachel).
"_"
$B$O!"L5L>JQ?t!#CM$O;D$i$J$$!#(B
"motherof(isaac,_)?"
$B$N"fatherof(_,_)"
$B$N"fatherof(joseph,X)"
$B$N"X"
$B$O!"(B"jacob"
$B$KB+G{(B(bind)$B$5$l$F$$$k!#(B
"motherof(C,leah)?"
$B$N"C=dinah"
$B$H$$$&B+G{$,5/$-$k$3$H$,$"$k!#(B
$B"!5,B'(B/Rules
parentof(C,P) :- motherof(C, P). -- P $B$,(B C $B$NJl$J$i!"(B P $B$O(B C $B$N?F$G$"$k!#(B
parentof(C,P) :- fatherof(C, P). -- P $B$,(B C $B$NIc$J$i!"(B P $B$O(B C $B$N?F$G$"$k!#(B
grandparentof(C,GP) :- parentof(C,P), parentof(P,GP).
-- C $B$N?F$,(B P $B$G!"$+$D!"(BP $B$N?F$,(B GP $B$J$i!"(BGP $B$O(B C $B$NADIcJl$G$"$k!#(B
ancestor(C,A) :- parentof(C,A).
ancestor(C,A) :- parentof(C,P), ancestor(P,A).
-- C $B$N?F$,(B P $B$G!"$+$D!"(BP $B$NAD@h$,(B A $B$J$i$P!"(BA $B$O(B C $B$NAD@h$G$"$k!#(B
$B"!%j%9%H(B/Lists
append([],Y,Y).
append([A|B],Y,[A|B1]) :- append(B,Y,B1).
$B"!(BAND$BJBNs$H(BOR$BJBNs(B/and-parallelism and or-parallelism
$BO@M}<0$NI>2A$K=gHV$N9M$(J}$O$J$$$N$G!"JBNs$K=hM}$r9T$C$F$b$h$$!#(B
$B"!(Bquicksort
quicksort(List,Sorted) :- qsort(List, Sorted, []).
qsort([],H,H).
qsort([A|B],H,T) :-
partition(B,A,S,L),
qsort(S,H,[A|T1]),
qsort(L,T1,T).
partition([],X,[],[]).
partition([A|B],X,[A|S],L) :- A<X, partition(B,X,S,L).
partition([A|B],X,S,[A|L]) :- A>=X, partition(B,X,S,L).
$B"!(BGHC (Guarded Horn Clauses)
Prolog $B$HF1MM$K!"#13,=R8lO@M}$K4p$E$$$F$$$k!#(B
$BJBNs(B($BJB9T(B)$BO@M}7?8@8l!#(B
$B"!(BGHC$B$N9=J8(B/Syntax of GHC
append([A|X1],Y,Z) :- true | Z = [A|Z1], append(X1,Y,Z1).
append([],Y,Z) :- true | Z=Y.
Prolog $B$J$i$3$&$J$k(B
append([A|X1],Y,[A|Z1]) :- append(X1,Y,Z1).
append([],Y,Y).
H 1 :- G 11, G 12,...,G 1n | B 11, B 12, ..., B 1m.
H 2 :- G 21, G 22,...,G 2n | B 21, B 22, ..., B 2m.
quicksort(Xs,Ys) :- true | qsort(Xs, Ys-[]). qsort([X|Xs],Ys0-Ys3) :- true | partition(Xs,X,S,L), qsort(S,Ys0-Ys1), Ys1=[X|Ys2], qsort(L,Ys2-Ys3). qsort([],Ys0-Ys1) :- true | Ys0 = Ys1. partition([X|Xs],A,S,L0) :- A<X | L0=[X|L1], partition(Xs,A,S,L1). partition([X|Xs],A,S0,L) :- A>=X | S0=[X|S1], partition(Xs,A,S1,L). partition([],A,S,L) := true | S=[], L=[].
1999$BG/$K!"%5%s!&%^%$%/%m%7%9%F%`%:
Jini $B$NL\I8$O!"%M%C%H%o!<%/$G(B Plug & Play $B$r
$BL\I8(B
JavaSpaces $B$O!"FbItE*$K(B Jini $B$N%k%C%/%"%C%W!&%5!<%S%9$N
Jini $B$N%/%i%9%i%$%V%i%j$O!"(B
JavaSpaces $B$N2s(B
$B$G>R2p$7$?(B
Apache River
$B$,MxMQ$G$-$k!#(B
Microsoft $B$N!"(BJini $B$KBP93$7$?5;=Q!#(B
$B"!(BUPnP (Universal Plugand Play)
$B"!%k%C%/%"%C%W!&%5!<%S%9(B/Loockup service in Jini
Jini$BCf?4E*$J5;=Q$,!"%k%C%/%"%C%W!&%5!<%S%9!#(B
$B%5!<%S%9$NEPO?$H8!:w(B
$B%k%C%/%"%C%W!&%5!<%S%9<+?H$b!":G=i$+$iCN$i$l$F$$$kI,MW$O$J$$!#(B $B%M%C%H%o!<%/>e$G<+F0E*$KC5$5$l$k!#(B Discovery $B$H(B Join$B!#(B
Java $B$N%*%V%8%'%/%H$,(B Lease$B!#(B
$B%j!<%94|4V$O!"1dD9$9$k$3$H$,$G$-$k!#(B $B1dD9$5$l$J$+$C$?(B lease $B$O!"%k%C%/%"%C%W!&%5!<%S%9$+$i:o=|$5$l$k!#(B $BEPO?$5$l$F$$$k%5!<%S%9$rL@<(E*$K:o=|$9$k;EAH$_$O!"B8:_$7$J$$!#(B
$B%5!<%S%9$,:o=|$5$l$?;~$K$O!"J,;67?%$%Y%s%HG[Aw%5!<%S%9$K$h$j4X78$7$F$$(B $B$k=j$KCN$i$5$l$k!#(B
$B%H%i%s%6%/%7%g%s$N%$%s%?%U%'!<%9$ODj$a$i$l$F$$$k$,!"6qBNE*$J
$B"!(BJini$B$r;H$&$N$KI,MW$H$5$l$F$$$k$b$N(B/Requirements to run Jini
IP$B%"%I%l%9$N3d$jEv$F$O!"(BJini$B$N0lIt$G$O$J$$!#(B
$B%5!<%S%9$NDs6!
ServiceIDLister $B%$%s%?%U%'!<%9$r(B implements $B$9$k!#(B
package com.sun.jini.lookup;
public interface ServiceIDListener extends java.util.EventListener {
void serviceIDNotify(net.jini.core.lookup.ServiceID serviceID);
}
$B%k%C%/%"%C%W!&%5!<%S%9$+$i%3!<%k%P%C%/$5$l$k!#(B
Discovery $B$N
$B?^(B1 $B%^%k%A%-%c%9%H$K$h$k(B Discovery/Discovery by multicast
$B?^(B2 Join
$B%0%k!<%W$O!"L>A0(B($BJ8;zNs(B)$B$G6hJL$5$l$k!#(B
Jini $B%Q%C%1!<%8$O!"(BJoinManager $B$H$$$&;2>H%/%i%9$r4^$`!#(B
public JoinManager(Object obj, Entry[] attrSets, ServiceIDListener callback, LeaseRenewalManager leaseMgr) throws IOException public JoinManager(Object obj, Entry[] attrSets, String[] groups, LookupLocator[] locators, ServiceIDListener callback, LeaseRenewalManager leaseMgr ) throws IOException
import java.rmi.*; public interface RemoteBall extends Remote { public void hit() throws java.rmi.RemoteException; }
import java.rmi.*; import java.rmi.server.*; import net.jini.core.lookup.*; import com.sun.jini.lookup.*; public class Ball extends UnicastRemoteObject implements RemoteBall, ServiceIDListener { public Ball() throws RemoteException { super(); } public void serviceIDNotify(ServiceID id) { System.out.println("ServiceId is "+id); } public void hit() { System.out.println("Ball has been hit"); } }
import java.rmi.*; import net.jini.core.entry.*; import net.jini.lookup.entry.*; import com.sun.jini.lookup.*; import com.sun.jini.lease.*; public class BallStarter { public static void main(String[] args) { try { System.setSecurityManager(new RMISecurityManager()); RemoteBall ball = (RemoteBall) new Ball(); LeaseRenewalManager renewal = new LeaseRenewalManager(); Entry[] attributes = new Entry [] { new Name("Jini enabled ball")}; JoinManager join = new JoinManager( ball, attributes, (Ball) ball, renewal ); System.out.println("Ball started and registered at Lookup-Server"); } catch (Exception e) { e.printStackTrace(); } } }
$B?^(B3 Lookup
$B%5!<%S%9$O!"public ServiceTemplate(ServiceID serviceID, Class[] serviceTypes, Entry[] attrSetTemplates)$B%5!<%S%9(B($B%*%V%8%'%/%H(B)$B$NC5$7J}(B
import java.rmi.*; import net.jini.core.discovery.*; import net.jini.core.lookup.*; public class Bat { public Ball ball; public void play(RemoteBall ball) { try { ball.hit(); System.out.println("I hit the ball"); } catch (RemoteException e) { System.out.println(e); } } public static void main (String[] args) { Bat bat = new Bat(); try { System.setSecurityManager(new RMISecurityManager()); LookupLocator locator = new LookupLocator("jini://localhost"); ServiceRegistrar registrar = locator.getRegistrar(); Class[] classes = new Class[] { RemoteBall.class }; ServiceTemplate template = new ServiceTemplate( null, classes, null); RemoteBall remoteBall = (RemoteBall) registrar.lookup(template); bat.play(remoteBall); } catch (Exception e) { e.printStackTrace(); } } }
$B?.Mj@-$,Dc$$%M%C%H%o!<%/$H!"$I$&@o$&J}K!$N#1$D!#(B
lease $B$K$O!"4|8B$,$"$k!#(B
$B4|8B$ND9$5$O!"8r>D2DG=!#(B $B4|8B$,C;$$(B(1$BJ,0J2
$B%j!<%9$NMxE@(B
Jini $B$N%5!<%S%9$rDs6!$7$F$$$k%*%V%8%'%/%H$O!"(BLease $B%$%s%?%U%'!<%9$r
public interface Lease { long FOREVER = Long.MAX_VALUE; ... long getExpiration(); void renew(long duration) throws LeaseDeniedException, UnknownLeaseException, RemoteException; void cancel() throws UnknownLeaseException, RemoteException; ... }getExpiration() $B$G!"%j!<%9$N;D$j;~4V$,$o$+$k!#%_%jICC10L!#(B
renew() $B$G1dD9$9$k!#(B $B1dD9$G$-$J$$;~$K$O!"(BLeaseDeniedException $B$,JV$5$l$k!#(B
$B$b$&;H$o$J$/$J$C$?;~$K$O!"(Bcancel() $B$G$-$k!#(B $B4|8B@Z$l$HF1$8$3$H$K$J$k!#(B
$B%j!<%9$N4IM}$K$O!"(BLeaseRenewalManager $B$r;H$&!#(B
Show the two methods that describe concurrency in the Actor models.
While a language processing system of Prolog executes a program sequentially, we can consider that we run the program in parallel. In the example quicksort, point out places that we can execute in parallel. Explain the places briefly.
Jini uses some techniques to support unreliable networks, such as wireless LANs. Choose an important one of these techniques, and explain it briefly.