2016-11-19 137 views
2

我試圖寫一個終端應用程序與Lwt。 基本上只要我的應用程序正在運行,我需要觀看終端輸入Lwt_io.read_line。Ocaml lwt永不結束循環

在我的程序運行時,是否有比下面(僞代碼)更好的方式來實現某種循環?

while true do 
    let _ = ignore (Lwt_main.run my_application) 
done 

我不確定這是否正確。每當my_application中的所有線程都完成時,Lwt_main.run會再次被調用&再次& ...

是否有其他更好的方法來處理這個問題?

回答

4

您通常會將主循環編寫爲遞歸函數,該函數計算爲一個線程,然後將該線程傳遞給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()) 

這可以編譯和運行:

ocamlfind opt -linkpkg -package lwt.unix -package lwt.ppx code.ml && ./a.out 

在粗略估計,這是在上面的代碼會發生什麼:

  1. echo_loop()應用在參數Lwt_main.run中。這立即開始評估Lwt_io.(read_line stdin),但代碼的其餘部分(從if表達式開始)放入一個閉包中,以便在read_line完成後運行。 echo_loop()然後評估爲正在進行的操作和緊接着的操作的組合。
  2. Lwt_main.run強制您的進程等待所有完成。但是,一旦read_line完成,如果行不是exit,則關閉會觸發write_line操作,然後是另一個關閉,它將遞歸調用echo_loop(),這會啓動另一個read_line,並且這可以無限期地繼續。
+1

我覺得自己像個白癡一樣沒有想到這個......感謝廣泛的迴應! – Seneca