Concurrency 在OCaml中使用Lwt时如何使循环中断
我正在编写代码来监视文件的内容。当程序到达文件的末尾时,我希望它干净地终止Concurrency 在OCaml中使用Lwt时如何使循环中断,concurrency,ocaml,ocaml-lwt,Concurrency,Ocaml,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_
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进行转义。我不确定bind的引擎盖下到底发生了什么,但我认为无论它在做什么,最终Lwt\u io.readline ic
都会到达文件的末尾,并返回end\u of\u file
异常,这可能会传递给处理程序,等等
如果我不得不猜测一个解决方案,我会想也许在
>=
定义的最后一个绑定中,我会包含一些If
检查。但我想我会检查Lwt\u io.read\u line
是否返回了End\u文件
,我认为这应该由处理程序处理 Lwt.wait
函数创建一个只能使用返回对的第二个元素解析的承诺,基本上,此函数永远不会终止:
let never_ready () =
let (p,_) = Lwt.wait in
p
这正是你写的
理想情况下,关于优雅终止,您应该在循环
功能中执行此操作,以便关闭通道并防止宝贵资源泄漏,例如
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
在处理程序的主体中
我对Lwt知之甚少,但是从对代码的简单阅读来看,我并不奇怪它会挂起,因为在文件的末尾
调用等待
然后扔掉解析器。所以它当然会等待。。。。您为什么不在这里使用return()
?