シミュレーションを試みる場合は、単にスレッドを使用するよりもはるかに多くのノードを制御する必要があります。少なくとも、大きな問題はありません。
このトピックに対する私の主観的なアプローチは、シミュレーションを完全に制御し続けるために、単純なシングルスレッドの仮想マシンを作成することです。OCamlでこれを行う最も簡単な方法は、モナドのような構造を使用することです(たとえば、Lwtで行われるように):
(* A thread is a piece of code that can be executed to perform some
side-effects and fork zero, one or more threads before returning.
Some threads may block when waiting for an event to happen. *)
type thread = < run : thread list ; block : bool >
(* References can be used as communication channels out-of-the box (simply
read and write values ot them). To implement a blocking communication
pattern, use these two primitives: *)
let write r x next = object (self)
method block = !r <> None
method run = if self # block then [self]
else r := Some x ; [next ()]
end
let read r next = object (self)
method block = !r = None
method run = match r with
| None -> [self]
| Some x -> r := None ; [next x]
end
チャネルに「送信に必要な時間」プロパティを追加するなど、ニーズに合ったより優れたプリミティブを作成できます。
次のステップは、シミュレーションエンジンを定義することです。
(* The simulation engine can be implemented as a simple queue. It starts
with a pre-defined set of threads and returns when no threads are left,
or when all threads are blocking. *)
let simulate threads =
let q = Queue.create () in
let () = List.iter (fun t -> Queue.push t q) threads in
let rec loop blocking =
if Queue.is_empty q then `AllThreadsTerminated else
if Queue.length q = blocking then `AllThreadsBlocked else
let thread = Queue.pop q in
if thread # block then (
Queue.push thread q ;
loop (blocking + 1)
) else (
List.iter (fun t -> Queue.push t q) (thread # run) ;
loop 0
)
in
loop 0
ここでも、エンジンを調整して、どのノードがどのスレッドを実行しているかを追跡したり、ノードごとの優先順位を維持して、あるノードが他のノードよりも大幅に遅いまたは速いことをシミュレートしたり、すべてのステップで実行するスレッドをランダムに選択したりできます。すぐ。
最後のステップはシミュレーションの実行です。ここでは、2つのスレッドが乱数を送受信します。
let rec thread name input output =
write output (Random.int 1024) (fun () ->
read input (fun value ->
Printf.printf "%s : %d" name value ;
print_newline () ;
thread name input output
))
let a = ref None and b = ref None
let _ = simulate [ thread "A -> B" a b ; thread "B -> A" b a ]