1

Akka アクターをメールボックスとしてのみ使用したい、つまり、それぞれが 1 つのリモート アクターを作成する n 個のスレッドを作成したい。

各スレッドは、他のスレッドのすべてのリモート アクターへの参照を取得し、それぞれのアクターを介して相互にメッセージを送信できるようにします。

アクターは次のように定義されます。

case class Receive
case class GroupReceive(id: Symbol)
case class GroupMsg[T](id: Symbol, msg: T)
class FooParActor(val distributor: Distributor) extends Actor
  with Stash {
  import context._

  val globalRank: Int = distributor.globalRank

  def doReceive(realSender: ActorRef, ID: Symbol) {
    unstashAll()
    become({
      case GroupMsg(ID, msg) =>
        realSender ! msg
        unbecome()
      case GroupMsg(otherId, msg) =>
        println(globalRank + ": stashing " + otherId)
        unbecome()
      case x => sys.error("bad msg: " + x)
    }, discardOld = false)
  }

  def receive = {
    case GroupReceive(id) =>
      doReceive(sender, id)
    case GroupMsg(id, x) =>
      stash()
    case x => sys.error("bad msg: " + x)
  }

}

メッセージを読むために、所有者スレッドはローカルのアクターに送信GroupReceive('someSymbol)し、次にそのローカル アクターが GroupMsg をスレッドに転送します。メッセージを読み取るためのスレッドの観点からのコードは、次のようになります。

def groupRcv[T](id:Symbol) = Await.result(aref ? GroupReceive(id), timeout.duration).asInstanceOf[T]

aref、このスレッドのローカル アクターへの参照です。

非常に単純な使用法と小さなメッセージでも、上記のパターンでデッドロック (5 秒のタイムアウト) が発生することがあります。GroupReceive(id)メッセージを受信した後、 doReceive(...): の最初のケースに入る前にアクターが失速するという問題に絞り込みましたcase GroupMsg(ID, msg) =>

doReceive 呼び出しに行く前に、アクターが実際に隠し場所にメッセージを持っていることを確認するために printout-traces を作成しましたが、何らかの理由でそれらを処理していないようです。上に示したコードは、 がの隠し場所GroupMsg()から失われる状態になる可能性がありますか? または、アクターがメッセージFooParActorを受信した後にデッドロックに陥る他の方法はありますか?GroupReceive()

4

1 に答える 1

2

あなたはそれをどこで使用してAwait.result()いますが、共有していません:groupRcvアクターが実行されているはずのスレッドを呼び出すと、もちろん枯渇する可能性があります (つまり、ターゲット アクターには実行可能なスレッドがないため、要求を完了することはありません)。

スレッドベースの同時実行性とアクターを不健全な方法で混在させているようですが、それをほのめかすだけでコードを表示していないため、そうしないように幅広いアドバイスしかできません。アクターをプログラミングするときは、スレッドを忘れてください。それらは Akka によって管理されます。特に、Akka のスレッドを悪用しないでください (つまり、これAwait.resultはおそらく独自の外部スレッド プールで動作しますが、ほとんどの場合、より優れた代替手段があります)。

最終的に、アクターを「メールボックスのあるスレッド」を作成するためだけに使用している場合、Akka は役に立たず、通常の従来の同時実行の落とし穴に突き当たることになります。

于 2013-03-06T20:08:29.957 に答える