我在OCaml。OCaml事件/频道教程?
我在寻找模拟通信节点以看短信通信方式不同等
下如何迅速传播的节点可以发送1和2接收固定的消息。我想明显的做法是让每个节点作为一个独立的线程。
显然你可以通过事件模块和通道获得线程来相互传递消息,但是我找不到任何这样的例子。有人能指出我正确的方向,还是给我一个简单的相关例子?
非常感谢。
我在OCaml。OCaml事件/频道教程?
我在寻找模拟通信节点以看短信通信方式不同等
下如何迅速传播的节点可以发送1和2接收固定的消息。我想明显的做法是让每个节点作为一个独立的线程。
显然你可以通过事件模块和通道获得线程来相互传递消息,但是我找不到任何这样的例子。有人能指出我正确的方向,还是给我一个简单的相关例子?
非常感谢。
如果你打算尝试一个模拟,那么你将需要更多的控制你的节点,而不是简单地使用线程将允许—或至少没有主要的痛苦。
我对该主题的主观方法是创建一个简单的单线程虚拟机,以保持对模拟的完全控制。 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
同样,你可以调整发动机跟踪哪个节点正在执行的线程,以保持每个节点的优先级,以便来模拟一个节点是大量慢或比别人快,或者随机选择一个线程在每一步执行,等等。
最后一步是执行一个模拟。在这里,我将有两个线程来回发送随机数。
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 ]
这听起来像你在考虑John Reppy的Concurrent ML。 OCaml here似乎有些类似。
答案@Thomas给出的答案也很有价值,但是如果你想使用这种并发编程风格,我会推荐阅读John Reppy的PhD thesis这是非常可读的,并给出了一个非常明确的处理CML和一些实质背后的动机其使用的例子。如果您对语义不感兴趣,那么如果跳过该部分,文档仍然可读。
是的,您可以使用OCaml的Event模块。您可以在在线O'Reilly book中找到其使用示例。
这是一个很棒的答案,非常鼓舞人心。 – Tiemen 2012-12-11 10:44:00