在OCAML中使用LWT时,如何使循环断裂



我正在编写代码来监视文件的内容。当程序到达文件的末尾时,我希望其清洁终止。

let log () : input_channel Lwt.t = 
  openfile "log" [O_RDONLY] 0 >>= fun fd -> 
  Lwt.return (of_fd input fd);;
let rec loop (ic: input_channel) = Lwt_io.read_line ic >>= fun text -> 
    Lwt_io.printl text >>= fun _ -> loop ic;;
let monitor () : unit Lwt.t = log () >>= loop;;
let handler : exn -> unit Lwt.t = fun e -> match e with
    | End_of_file -> let (p: unit Lwt.t), r = Lwt.wait() in p
    | x -> Lwt.fail x;;
let main () : unit Lwt.t = Lwt.catch monitor handler;;
let _ = Lwt_main.run (main ());;

但是,当读取文件并到达末尾时,程序不会终止,它只是悬挂,我必须用Ctrl C逃脱。我不确定带有绑定的引擎盖下发生了什么,但我想知道它在做什么,最终Lwt_io.readline ic最终应该击中文件的末尾并返回End_of_file例外,大概会将其传递给处理程序等。

如果我不得不猜测一个分辨率,我认为也许在>>=的定义的最后一个绑定中,我将包括一些if检查。但是我想,我会检查Lwt_io.read_line是否返回End_of_file,尽管我应该由handler处理。

Lwt.wait函数创造了一个只能使用返回对的第二个元素解决的承诺,基本上,此函数永远不会终止:

let never_ready () = 
  let (p,_) = Lwt.wait in
  p

这正是您写的。

关于优雅的终止,理想情况下,您应该在loop功能中执行此操作,以便您可以关闭渠道并防止宝贵资源的泄漏,例如,

let rec loop (ic: input_channel) = 
  Lwt_io.read_line ic >>= function
  | exception End_of_file -> 
    Lwt.close ic
  | text->
    Lwt_io.printl text >>= fun () -> 
    loop ic

但是,对您的代码的最小更改将是使用Lwt.return ()而不是Lwt.wait中的CC_11。

相关内容

  • 没有找到相关文章

最新更新