0

私は Scala Actors と協力して、スケジューラ アルゴリズムの実装を試みていました。

スケジューラは、計算中に何らかの「対話」関数を呼び出す 2 つの関数を受け取ります。例えば:

def func1(x:Int, y:Int)(scheduler:MyScheduler):Int = {
   var z = 0
   if (scheduler.interact(1)) {
       return 7
   }
   z = x * y
   for (c <- 1 to 10) {
       if (scheduler.interact(z)) {
           return z
       }
       z = z * c
   }
   z
}

ここで、スケジューラは両方の関数を順次実行する必要があり、関数の実行が「対話」に達するたびに、スケジューラは同じ関数を続行するか一時停止して他の関数計算を起動するかを決定します。

毎回どのジェネレーターのnext()を呼び出すかを決定するスケジューラーを使用して、python ジェネレーターを実行するようなものと考えることができます。

私は Scala Actors を使用してこれを実装しました。各関数はアクターで実行され、interact操作はメイン スレッド (スケジューラ) に何らかの値を返し、メイン スレッドからのメッセージを待機するために "receive" を呼び出します。

「受信」の代わりに「反応」を使用できないことに注意してください。これは、実行が受信ブロックから抜け出す (そして「対話」関数から戻る) 必要があるためです。

次に、 SingleThreadedSchedulerを使用してアクターを常にメイン スレッドで実行することにより、実装を改善することを考えました。

ただし、「react」とは異なり、「receive」関数は実行をブロックする新しいスレッドを作成しようとするようです。

「反応」と「受信」の間に、実行が「受信」のようにブロックを離れますが、「反応」のように新しいスレッドを作成しないようにするものはありますか? または、他の方法でスレッド数を 1 に制限できますか?

A-Posteriori scala の継続について読みましたが、これにはコードの変更が多すぎます (そして、scala の継続を使用するのは少し複雑であることに同意するでしょう...)。

ありがとう

4

1 に答える 1

0

この種の課題は、アクター モデルが必ずしも正しい抽象化ではないという証拠です。あなたが言うように、通常、継続は物事をより複雑にし、あなたのコードを読んでいる人にとっては、おそらくむしろあいまいにさえなります.

私自身の好みは、スレッドが実際に何をしようとしているのかについて明確に推論する方法を見つけることです. 幸いなことに、これは優れた JCSP API (UKC から) を使用して可能です。これは Java API ですが、Scala でも問題なく動作し、成熟して安定しています (Oxford Uni の純粋な Scala プロジェクトがありますが、これはまだ成熟していない可能性があります)。JCSP は Hoare の CSP を実装しています。これは数学的代数ですが、イベント ドリブンであることを認識すれば簡単に使用できます。アクターは JCSP で簡単にモデル化できますが、その逆はできません。

アプリケーションでは、スケジューラは独自の CS-Process (別名 Java スレッド) を持ち、受信したイベントに基づいて独自の状態とライフサイクルを決定します。これにより、2 つの関数を同時に呼び出すのではなく、一連のスレッド アクティビティの一部として、順番に呼び出すことができます。

http://www.cs.kent.ac.uk/projects/ofa/jcsp/は背景資料を提供します。jar はhttp://mvnrepository.com/artifact/org.codehaus.jcsp/jcspにあります。

于 2012-10-07T08:19:33.773 に答える