$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!"
https://www.cs.tsukuba.ac.jp/~yas/cs/csys-2025/2025-06-20
$B$"$k$$$O!"
https://www.cs.tsukuba.ac.jp/~yas/cs/
https://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) become$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)))))))
import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.{ActorRef, Behavior} object Counter { sealed trait Command case object Increment extends Command final case class GetValue(replyTo: ActorRef[Value]) extends Command final case class Value(n: Int) def apply(): Behavior[Command] = counter(0) private def counter(n: Int): Behavior[Command] = Behaviors.receive { (context, message) => //$B"(#1(B message match { case Increment => val newValue = n + 1 context.log.debug("Incremented counter to [{}]", newValue) counter(newValue) //$B"((B2 case GetValue(replyTo) => replyTo ! Value(n) Behaviors.same } } }
// 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
defmodule Counter do def start(initial_count) do spawn fn -> listen(initial_count) end end def listen(count) do receive do :inc -> listen(count + 1) {sender, :val} -> send sender, count listen(count) end end end iex> counter_pid = Counter.start(10) #PID<...> iex> send counter_pid, :inc :inc iex> send counter_pid, :inc :inc iex> send counter_pid, :inc :inc iex> send counter_pid, {self, :val} {#PID<...>, :val} iex> receive do ...(13)> value -> value ...(13)> end 13
$B%+%&%s%?$NNc!#(B
1: #!/opt/local/bin/ruby3.0 2: 3: Warning[:experimental] = false 4: 5: class CounterActor 6: def initialize(val) 7: @r = Ractor.new(val) {|val| 8: loop { 9: msg = Ractor.receive() 10: case msg 11: in [:inc] 12: val += 1 13: in [:getvalue, c] 14: c.send(val) 15: end 16: } 17: } 18: end 19: def send( msg ) 20: @r.send( msg ) 21: end 22: end 23: 24: c = CounterActor.new(10) 25: 26: c.send([:inc]) 27: c.send([:inc]) 28: c.send([:getvalue, Ractor.current()]) 29: v = Ractor.receive() 30: printf("Counter value == %d\n",v)$B
$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
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
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
append([],Y,Y). append([A|B],Y,[A|B1]) :- append(B,Y,B1).
$B?^(B? Prolog $B$N(B append
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?^(B? Prolog $B$K$h$k%/%$%C%/%=!<%H(B
quicksort $B$K$"$kJBNs@-!#(BParallelism in quicksort.H :- G 1, G 2,...,G n | B 1, B 2, ..., B m.
$B!V(B|$B!W$O!"%3%_%C%H1i;;;R!#(B G 1, G 2,...,G n $B$O%,!<%IIt!#(B B 1, B 2, ..., B m $B$O!"%\%G%#It!#(Bappend([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).
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 Plug and 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
CS$B@l96!&>pJsM}9)3X0L%W%m%0%i%`$N653X%^%M%8%a%s%H0Q0w2q$G$O!"(B
$B650i$N2~A1$N$?$a$K!"3X@8$N3'$5$s$K
$B%"%s%1!<%H$O(BTWINS$B$+$i2sEz$7$F$/$@$5$$!#(B
$B
$BJ#?t$N650w$,9V5A$rC4Ev$7$F$$$k>l9g$O!"
$B$J$*!"3'$5$s$NI>2A$,@.@S$K1F6A$9$k$3$H$O0l@Z$"$j$^$;$s!#(B
$B$^$?!"I>2A7k2L$r650i$N2~A10J30$NL\E*$KMxMQ$9$k$3$H$O$"$j$^$;$s$7!"(B
$BI>2A7k2L$r8x3+$9$k>l9g$K$O8D?M$rFCDj$G$-$k$h$&$J>pJs$O4^$a$^$;$s!#(B
Department of Computer Science/Master's and Doctoral Programs in
Computer Science conducts a survey of all students for the purpose of
evaluating and improving instruction.
Please complete this questionnaire on TWINS between June 20 and July 17.
Please answer with respect to the overall impression of instruction
given in the course regardless of the number of lecturers. Note that
opinions or questions concerning individual instructors can be entered
in the free-entry cell on the other side of this question sheet.
These answers will not affect your academic grades. The result will
not be used for any purpose other than instruction evaluation and its
further improvement. When the summarized information of this
questionnaire is released to the public (for FD activities), no
private information about you will be included.
The following sentences describe the Actor models.
Write "Yes" at the beginning of each sentence if it is correct.
Write "No" at the beginning of each sentence if it is incorrect.
$B"#N}=,LdBj(B(exercise)9 $BJB9T%W%m%0%i%_%s%08@8l(B(2)/Concurrent Programming Languages(2)
$B!zLdBj(B(901) $B%"%/%?%b%G%k(B/The Actor models
$B0J2<$NJ8$O!"(BActor $B%b%G%k$K$D$$$F@bL@$7$F$$$k!#(B
$B@5$7$$J8$N@hF,$K(B Yes$B!"4V0c$C(B
$B$?$b$N$K(B No $B=q$-$J$5$$!#(B
We can describe concurrency by creating multiple actors.
$B!zLdBj(B(902) $B%"%/%?%b%G%k$NA`:n(B/The operations in the Actor models
Scala,
Kotlin,
Elixir, $B$*$h$S(B
Ruby Ractor
$B$G$O!"(B
$B$"$k
In Scala, Kotlin, Elixir, and Ruby Ractor, we can write a program based on a kind of the actor model. Choose one language from these languages, and provide how to describe the following operations in the language.
The Jini technology uses the idea of leasing. Describe its reason by using an example.
$B
$B