Ocaml lwt 永无止境的循环

Sen*_*eca 3 ocaml ocaml-lwt

我正在尝试使用 Lwt 编写一个终端应用程序。基本上,只要我的应用程序正在运行,我就需要使用 Lwt_io.read_line 来观察终端的输入。

有没有比以下(伪代码)更好的方法来在我的程序运行时实现某种循环?

while true do
  let _ = ignore (Lwt_main.run my_application)
done
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是正确的方法。每次 my_application 中的所有线程完成时,Lwt_main.run 就会一次又一次地被调用...

Lwt 是否有其他或更好的方法来处理这个问题?

ant*_*ron 5

您通常会将主循环编写为递归函数,其计算结果为一个线程,然后将该线程一次传递给Lwt_main.run. 这是一个小例子:

let () =
  let rec echo_loop () =
    let%lwt line = Lwt_io.(read_line stdin) in
    if line = "exit" then
      Lwt.return_unit
    else
      let%lwt () = Lwt_io.(write_line stdout line) in
      echo_loop ()
  in

  Lwt_main.run (echo_loop ())
Run Code Online (Sandbox Code Playgroud)

可以使用以下命令编译和运行:

ocamlfind opt -linkpkg -package lwt.unix -package lwt.ppx code.ml && ./a.out
Run Code Online (Sandbox Code Playgroud)

粗略地说,上面的代码中发生的是这样的情况:

  1. echo_loop ()应用于 的论证中Lwt_main.run。这会立即开始计算Lwt_io.(read_line stdin),但其余代码(从表达式开始if)将被放入闭包中,以便在完成后运行read_line。然后评估正在进行的操作和关闭echo_loop ()的组合。read_line
  2. Lwt_main.run强制您的进程等待所有操作完成。但是,一旦read_line完成,如果该行不是exit,则闭包会触发一个write_line操作,然后是另一个闭包,该闭包会递归echo_loop ()调用,从而启动另一个read_line,并且这可以无限期地继续下去。