2

アクターが値を送信者に返す方法と、それを変数に格納する方法を知りたいです。

たとえば、2 つの数値の平方和を求めて出力する必要があるとします。

つまり、合計 = a 2 + b 2

私には2人の俳優がいます。1 つのアクターは、渡された任意の数値の 2 乗を計算します (たとえば、SquareActor)。もう一方のアクターは、2 つの数値 (a 、b) を に送信し、SquareActorそれらの合計を計算します (たとえば、SumActor) 。

/** Actor to find the square of a number */

class SquareActor (x: Int) extends Actor
{
  def act()
  {
    react{
        case x : Int => println (x * x)  
        // how to return the value of x*x to "SumActor" ?
    }
  } 
}

/** Actor to find the sum of squares of a and b */

class SumActor (a: Int, b:Int) extends Actor
{
  def act()
  {
    var a2 = 0
    var b2 = 0        

    val squareActor = new SquareActor (a : Int)   
    squareActor.start

    // call squareActor to get a*a 
    squareActor ! a 
// How to get the value returned by SquareActor and store it in the variable 'a2' ?

    // call squareActor to get b*b 
    squareActor ! b
// How to get the value returned by SquareActor and store it in the variable 'b2' ?

    println ("Sum: " + a2+b2)
  } 
}

上記が不可能な場合はご容赦ください。俳優に対する私の基本的な理解自体が間違っているのではないかと思います。

4

2 に答える 2

4

アッカを使う

Scala 2.10 以降、Akkaアクター ライブラリは標準ライブラリに統合されていることに注意してください。これは一般に、標準のアクター ライブラリよりも優れていると考えられているため、それに慣れることは有益です。

先物を使用する

また、 Futuresを使用すると、達成したいことがより簡単で優れた (構成が向上する) ことにも注意してください。AFuture[A]は、可能な同時計算を表し、最終的にタイプ の結果を生成しAます。

def asyncSquare(x: Int): Future[Int] = Future(x * x)
val sq1 = asyncSquare(2)
val sq2 = asyncSquare(3)

val asyncSum = 
  for {
    a <- sq1
    b <- sq2
  }
  yield (a + b)

asyncSquareできるだけ早く (独立した) 計算を開始するために、結果は事前に照会されることに注意してください。内包表記内に呼び出しを配置するとfor、可能な同時実行性を使用せずに、実行がシリアル化されます。

内包表記、、、、それらでFuture-s を使用し、最後に、ブロッキング操作である を使用するか、登録されたコールバックを使用して、計算された値を取得できます。formapflatMapzipsequenceAwait

アクターで Future を使用する

askアクターからできると便利です。結果は次のようになりFutureます。

val futureResult: Future[Int] = (someActor ? 5).mapTo[Int]

mapToアクターのメッセージ パッシング インターフェイスは型指定されていないため、を使用する必要があることに注意してください(ただし、型指定されたアクターは存在します)。

結論

ステートレスな計算を並行して実行したい場合は、単純なFutures に固執してください。ステートフルでローカルな計算が必要な場合でも、Future自分で状態を使用してスレッド化できます (または、そのビジネスに取り組んでいる場合は、scalaz StateT モナド トランスフォーマー + Future をモナドとして使用します)。グローバルな状態を必要とする計算が必要な場合は、その状態をアクターに分離し、おそらくFutures を使用してそのアクターと対話します。

于 2012-09-08T07:55:59.380 に答える
2

アクターはメッセージ パッシングによって機能することを思い出してください。SquareActorしたがって、 からへの応答を取得するには、SumActorからメッセージとして送信し、SquareActorにハンドラを追加する必要がありSumActorます。

また、SquareActorコンストラクターには整数パラメーターは必要ありません。

つまり、あなたSquareActorの では、単に print する代わりに、次のx * xように渡しますSumActor:

class SquareActor extends Actor
{
  def act()
  {
    react{
        case x : Int => sender ! (x * x)  
    }
  } 
}

(sender反応しているメッセージを送信したアクターにメッセージを送信します。)

で、およびにSumActor送信した後、受信した応答メッセージを処理します。abSquareActor

react {
  case a2 : Int => react {
    case b2 : Int => println ("Sum: " + (a2+b2))
  }
}
于 2012-09-08T04:04:51.757 に答える