2016-12-05 92 views
2

我正在MirageOS(Unix)之上開發Ocaml的Web服務,此刻我在Lwt.async()上遇到了一些問題。 LWT中文檔指出以下幾點:Lwt.async()未按預期方式工作

val async : (unit -> 'a t) -> unit

異步˚F啓動一個線程,而不 等待結果。如果失敗(現在或稍後),則給予Lwt。async_exception_hook的例外是 。

如果你想啓動一個可能會失敗並且不在乎它的返回值是什麼的線程,或者它終止了 (例如,因爲它正在循環),你應該使用這個函數。

因此,我立即認爲Lwt.async是一個很好的候選人,可以運行一些測試並檢查實際上執行的是異步的。不幸的是,它不能按預期工作。我的代碼如下:

let http_callback conn_id req _body = 
    Lwt.return(Uri.path (Cohttp.Request.uri req)) 
    >>= function 
    | "/tester" -> Cohttp_lwt_body.to_string _body >>= fun res -> 
     log_lwt ~inject:(fun f -> f "Testing") >>= fun() -> 
     Lwt.async(fun() -> TEST.start 100 res !listOfIP); 
     H.respond_string ~status:`OK ~body:("DONE")() 
    in 
    let spec = H.make ~callback:http_callback() in 
    CON.listen conduit (`TCP 8080) (H.listen spec) 

爲了清楚起見,TEST.start執行一系列線程操作。我認爲Lwt.async裏面的函數在做什麼並不重要,因爲無論返回/是否應該被忽略。我錯了嗎?

最後,我的問題是:爲什麼實際上客戶端必須等待線程接收OK響應?有或沒有異步的行爲基本上是相同的。

回答

2

如果異步線程阻塞等待某些內容,控制權將只切換回HTTP處理程序。如果它只是在完成之前使用CPU 100%,則異步線程可能會首先運行到完成狀態。嘗試在測試中進行睡眠檢查。

+0

感謝您的回答,將盡快嘗試。 –

+0

我用Lwt.return(Unix.sleep 10)完全替換了TEST.start調用的那段代碼,但結果完全一樣。當我運行curl -X POST --data東西http://10.0.0.2:8080/tester控制檯掛起,我必須等待10秒才能得到答覆。我的意思是,如果我從輔助線程調用睡眠,我真的不希望主線程停止.. –

+2

Lwt線程不搶先。他們實際上是承諾。嘗試使用'Lwt_unix.sleep 10.'而不是'Lwt.return(Unix.sleep 10)'。 – antron