OCaml событие / канал учебник? - PullRequest
7 голосов
/ 12 февраля 2012

Я нахожусь в OCaml.

Я хочу смоделировать узлы связи, чтобы посмотреть, как быстро сообщения распространяются по различным схемам связи и т. Д.

Узлы могут 1. отправлять и 2. получить фиксированное сообщение.Я предполагаю, что очевидная вещь, которую нужно сделать - это иметь каждый узел в качестве отдельного потока.

Очевидно, вы можете заставить потоки передавать сообщения друг другу, используя модуль событий и каналы, но я не могу найти никаких примеров этого.Может ли кто-нибудь указать мне правильное направление или просто привести простой пример?

Большое спасибо.

Ответы [ 3 ]

8 голосов
/ 12 февраля 2012

Да, вы можете использовать Event модуль OCaml. Вы можете найти пример его использования в онлайн O'Reilly book .

6 голосов
/ 13 февраля 2012

Если вы собираетесь попробовать симуляцию, вам понадобится намного больше контроля над вашими узлами, чем простое использование потоков позволит & mdash; или, по крайней мере, без серьезных болей.

Мой субъективный подход к этой теме - создать простую однопоточную виртуальную машину, чтобы сохранить полный контроль над симуляцией. Самый простой способ сделать это в 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 ]        
5 голосов
/ 12 февраля 2012

Звучит так, будто вы думаете о Concurrent ML Джона Реппи. Кажется, что-то похожее для OCaml здесь .

Ответ, который дал @Thomas, также ценен, но если вы хотите использовать этот стиль параллельного программирования, я бы рекомендовал прочитать докторскую диссертацию Джона Реппи , которая чрезвычайно удобочитаема и дает очень четкое представление о мотивация CML и некоторые существенные примеры его использования. Если вас не интересует семантика, документ можно прочитать, если вы пропустите эту часть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...