OCaml event / channel tutorial?

I'm at OCaml.

I am looking to simulate communication nodes, to see how fast messages are spreading in different communication schemes, etc.

Nodes can 1. send and 2. receive a fixed message. I think it is obvious that each node is a separate thread.

Apparently, you can receive streams for sending messages to each other using the module and Event channels, but I can not find examples of this. Can someone point me in the right direction or just give me a simple example?

Many thanks.

+7
source share
3 answers

If you are going to try the simulation, you will need a lot more control over your nodes than just using threads will allow - or at least without serious pain.

My subjective approach to this topic would be to create a simple single-threaded virtual machine to provide complete control over the simulation. The easiest way to do this in OCaml is to use a monad-like structure (as is done in Lwt, for example):

(* 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 rx 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 

You can create the best primitives that suit your needs, for example, add the "time required for transmission" property to your channels.

The next step is to determine the modeling mechanism.

 (* 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 tq) 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 tq) (thread # run) ; loop 0 ) in loop 0 

Again, you can configure the engine to track that the node is executing this thread, to maintain priorities for the node, to simulate a single node that was significantly slower or faster than others, or arbitrarily choose a thread to execute at each step, etc.

The last step is the simulation. Here I will have two threads sending random numbers back and forth.

 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" ab ; thread "B -> A" ba ] 
+6
source

Yes, you can use the OCaml Event module. You can find an example of its use in the O'Reilly online book.

+8
source

Sounds like you're thinking of John Reppy Concurrent ML . Something similar for OCaml seems to be here .

@Thomas's answer was also valuable, but if you want to use this parallel programming style, I would recommend John Reppy's Ph.D. dissertation , which is extremely readable and gives a very clear idea of ​​CML motivation and some significant examples of its use. If you are not interested in semantics, the document remains readable if you skip this part.

+5
source

All Articles