7

私は簡単なプログラムを持っています:

import scalaz._
import stream._

object Play extends App {
  val in1 = io.linesR("C:/tmp/as.txt")
  val in2 = io.linesR("C:/tmp/bs.txt")

  val p = (in1 merge in2) to io.stdOutLines
  p.run.run
}

ファイルas.txtには 5 つaの が含まれており、ファイルbs.txtには 3 つの が含まれていますb。次のような出力が表示されます。

a
b
b
a
a
b
a
a
a

ただし、次のように宣言を変更するとin2:

val in2 = io.stdInLines

次に、予期しない動作だと思うものを取得します。ドキュメント1によると、プログラムは、どちらのストリームがより速く供給できるかに応じて、各ストリームから非決定論的にデータをプルする必要があります。これは、一連の s がすぐにコンソールに表示されることを意味しますaが、これはまったく発生しません。

確かに、 を押すまでENTER何も起こりません。次の要素を取得するストリームをランダムに選択し、そのストリームがブロックされていた場合、マージされたプロセスもブロックされた場合 (他のストリームにデータが含まれていても)。

何が起こっている?

1 - わかりました。文書はほとんどありませんが、 Dan Spiewakは講演の中で、最初にデータを提供した人は誰でもと非常に明確に述べまし

4

1 に答える 1

6

問題は の実装にありstdInLinesます。それはブロッキングであり、決してTask.forkスレッドではありません。

の実装を次のように変更してみてくださいstdInLines

def stdInLines: Process[Task,String] =
    Process.repeatEval(Task.apply { 
    Option(scala.Console.readLine())
    .getOrElse(throw Cause.Terminated(Cause.End))
})

オリジナルio.stdInLinesは同じスレッドで実行readLine()されているため、何かを入力するまで常にそこで待機します。

于 2014-11-18T21:24:48.080 に答える