我在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