1. ホーム
  2. scala

[解決済み] Scalaのアクター:受信と反応

2022-10-25 20:46:55

質問

最初に断っておきますが、私はJavaの経験がかなりありますが、関数型言語には最近になって興味を持ち始めました。最近、私はScalaを見始めましたが、それは非常に素晴らしい言語のように思われます。

しかし、Scala の Actor フレームワークについては Scalaでプログラミング を読んでいて、一つ分からないことがあります。30.4章では react の代わりに receive はスレッドを再利用することを可能にします。スレッドはJVMで高価なので、これはパフォーマンスにとって良いことです。

これはつまり、私が react の代わりに receive というように、好きなだけActorを起動できるのでしょうか?Scalaを発見する前に、私はErlangで遊んでいたのですが、その作者は プログラミングErlang は20万以上のプロセスを汗をかかずに生成することを自慢しています。Javaスレッドでそれをするのは嫌ですね。Erlang(とJava)と比べて、Scalaではどんな制限があるのでしょうか?

また、このスレッドの再利用はScalaでどのように機能するのでしょうか?単純化するために、私が1つのスレッドしか持っていないと仮定しましょう。私が開始するすべてのアクターは、このスレッドで順次実行されるのでしょうか、それとも何らかのタスク切り替えが行われるのでしょうか?たとえば、互いにメッセージを交換する 2 つのアクターを起動する場合、それらが同じスレッドで起動されるとデッドロックの危険がありますか?

によると Scalaでのプログラミング を使用するようにアクターを書くと react を使うようにアクターを書くことは receive . これはもっともなことのように聞こえますが,なぜなら react は返らないからです。しかし、この本では、どのようにすれば react を使ってループの中に Actor.loop . その結果、次のようになります。

loop {
    react {
        ...
    }
}

というのは、私には、かなり似ていると思える。

while (true) {
    receive {
        ...
    }
}

という、この本の序盤で使用されているものがあります。それでも、この本では、実際には、プログラムには少なくとも数個の receive が必要だと書いてあります。では、何が足りないのでしょうか?何が receive ができるのでしょうか? react ができない、返す以外に?そして、なぜ私は気になりますか?

最後に、私が理解していないことの核心に迫ります:この本では、どのように react を使うことで、スレッドを再利用するためにコールスタックを破棄することが可能になることについて、この本は言及し続けています。これはどのように機能するのでしょうか。なぜ、コールスタックを破棄する必要があるのでしょうか?また、関数が例外を投げて終了したときに、なぜコールスタックを破棄できるのでしょうか( react ) で終了し、リターンすることで終了しないのはなぜでしょうか。 receive )?

という印象があります。 Scalaでのプログラミング は、ここでの重要な問題のいくつかに触れていない印象があります。それ以外は本当に素晴らしい本なので、残念です。

どのように解決するのか?

まず、各アクターが待機している receive はスレッドを占有しています。もしそれが決して何も受け取らなければ、そのスレッドは決して何もしないでしょう。アクターは react 上のアクターは、何かを受け取るまでどのスレッドも占有しません。いったん何かを受け取ると、スレッドがそれに割り当てられ、その中で初期化されます。

さて、この初期化の部分が重要です。受信するスレッドは何かを返すことが期待されますが、反応するスレッドはそうではありません。そのため、前回のスタック状態である react の終わりにある以前のスタック状態は完全に捨てられるし、捨てられる。スタック状態を保存または復元する必要がないため、スレッドの開始がより速くなります。

1つまたは他のものを必要とするかもしれないさまざまなパフォーマンス上の理由があります。ご存知のように、Javaであまりにも多くのスレッドを持つことは良いアイデアではありません。一方、アクターをスレッドにアタッチしてからでないと react を実行する前にスレッドにアタッチする必要があるので receive よりも、メッセージの react をそれに追加します。そのため、多くのメッセージを受け取るが、それに対してほとんど何もしないアクターがある場合、追加の遅延のために react の追加遅延は、あなたの目的には遅すぎるかもしれません。