3
var num =0
var num2 = 3333
val p2 = Process.eval {
  Thread.sleep(10000)
  Task.delay {
    Thread.sleep(10000)
    num2 = num2 + 1
    s"hi ${num2}"
  }
}.repeat.take(15)

//p2: scalaz.stream.Process[[x]scalaz.concurrent.Task[x],String] =
// Await(scalaz.concurrent.Task@5a554f1c,
//<function1>,Halt(scalaz.stream.Process$End$),Halt(scalaz.stream.Process$End$))

val p1 = Process.eval {
  Thread.sleep(2000)
  Task.delay { 
    Thread.sleep(2000)
    num = num + 1
    s"hi $num"
  }
}.repeat.take(15)

//p1: scalaz.stream.Process[[x]scalaz.concurrent.Task[x],String] = 
// Await(scalaz.concurrent.Task@7a54e904,
// <function1>,Halt(scalaz.stream.Process$End$),Halt(scalaz.stream.Process$End$))

// this interleaves them and I get disjunctions showing me their order
(p1 either p2).map(println).run.run

// this gives me the strings that are interleaved
(p1 interleave p2).map(println).run.run

2 つのプロセスの組み合わせであるプロセスをどのように取得しますか?

スリープが短いものを探して、より頻繁に発生し、遅いプロセスの前に複数回表示されることを確認しています。時間を割いてこれを読んでくれた人、特に洞察を共有できる人に感謝します。

4

1 に答える 1

4

エリック、

非決定論的インターリーブは Process.wye を介して scalaz-stream に実装されており、実際どちらも Y を使用する非決定論的コンビネータの 1 つです。それらが左/右にインターリーブする理由は、公平にしようとするためと、スレッドをブロックするためです。2 番目のものより遅い 1 つの側を作成しようとすると、どちらかが非決定論的であることがわかります。

非決定的な動作を実現するには、実際には2つのスレッドから実行されるプロセスが必要であることに注意してください.p1プロセスは実際には単一のスレッドをブロックしているため、シナリオでは順序は常に決定的です.

試す:

val p1 = Process(1,2,3).toSource
val p2 = Process(10) fby Process.sleep(1 second) fby Process(20,30).toSource

(p1 either p2).runLog.run.foreach(println)

それは放出するはずです

-\/(1)
\/-(10)
-\/(2)
-\/(3)
\/-(20)
\/-(30)
于 2014-02-20T13:25:35.023 に答える