5

1 つのホストで 2 つのリモート アクターを開始し、送信されたものをすべてエコーします。次に、( !! を使用して) いくつかのメッセージを両方のアクターに送信する別のアクターを作成し、これらのアクターからの応答を保持する Future オブジェクトのリストを保持します。次に、この List をループして、各 Future の結果をフェッチします。問題は、アクターが応答を送信したと主張しているにもかかわらず、ほとんどの場合、一部の先物が返されないことです。問題はランダムに発生し、リスト全体を通過することもありますが、ほとんどの場合、ある時点でスタックして無期限にハングします。

私のマシンで問題を引き起こすコードは次のとおりです。

Sink.scala:

import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.Exit
import scala.actors.remote.RemoteActor
import scala.actors.remote.RemoteActor._

object Sink {
  def main(args: Array[String]): Unit = {
     new RemoteSink("node03-0",43001).start()
     new RemoteSink("node03-1",43001).start()
   }
}
class RemoteSink(name: String, port: Int) extends Actor
{
 def act() {
    println(name+" starts")
    trapExit=true
    alive(port)
    register(Symbol(name),self)

    loop {
        react {
            case Exit(from,reason) =>{
                    exit()
            }
            case msg => reply{
                    println(name+" sending reply to: "+msg)
                    msg+" back at you from "+name
                }
        }
    }
 }
}

ソース.scala:

import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.remote.Node;
import scala.actors.remote.RemoteActor
import scala.actors.remote.RemoteActor._

object Source {
    def main(args: Array[String]):Unit = {
        val peer = Node("127.0.0.1", 43001)
        val source = new RemoteSource(peer)
        source.start()
    }
}
class RemoteSource(peer: Node) extends Actor
{
    def act() {
        trapExit=true
        alive(43001)
        register(Symbol("source"),self)

        val sinks = List(select(peer,Symbol("node03-0"))
                                   ,select(peer,Symbol("node03-1"))
                                )
        sinks.foreach(link)

        val futures = for(sink <- sinks; i <- 0 to 20) yield    sink !! "hello "+i
        futures.foreach( f => println(f()))

        exit()
    }
}

私は何を間違っていますか?

4

2 に答える 2

2

あなたの問題は次の行によるものだと思います:

futures.foreach( f => println(f()))

すべての先物をループして、それぞれを順番にブロックし、その結果を待ちます。先物をブロックすることは一般的に悪い考えであり、避けるべきです。代わりにやりたいことは、将来の結果が利用可能になったときに実行するアクションを指定することです。これを試して:

futures.foreach(f => f.foreach(r => println(r)))

これは、理解のための別の言い方です。

for (future <- futures; result <- future) { println(result) }

このブログ エントリは、future のブロックの問題と、モナドの future がそれをどのように克服するかについての優れた入門書です。

于 2010-07-28T20:50:02.000 に答える
0

私も似たような事例を見たことがあります。スレッド内のコードが特定の種類の例外をスローして終了すると、対応する future.get が返されません。java.lang.Error と java.lang.NoSuchMethodError の例外を発生させてみることができます。後者の対応する未来は二度と戻りません。

于 2014-11-05T17:42:03.307 に答える