Ocaml Lwt.wait()
Ocaml Lwt.wait()
我有一个关于 lwt 的等待函数的问题,以及我如何在我自己的自定义函数中使用它,这将 return 一个 Lwt.t 线程。先给大家举个例子。
open Lwt_io
open Lwt.Infix
let i, o = Lwt_io.pipe()
let get_int () =
let t, w = Lwt.wait() in
(*what do I do here to provide the sleeping thread*)
(*with a possible integer reply*)
Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;
t
let ans = get_int()
在上面的函数中,我调用 wait 来生成一个休眠线程及其唤醒器,但我不确定如何为休眠线程提供一个可能的整数回复,并且仍然能够 return 一个休眠线程来自get_int 函数。我提供了一行 (Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;) 这似乎有效,但我不确定这是否是完成此操作的正确方法。有任何指示、链接或评论吗?
注意:我问这个问题是因为在函数中添加 Lwt_io.read_int(i) 是多余的。我可以删除 get_int 函数并调用 Lwt_io.read_int(i) 但我很好奇如果没有冗余你将如何做到这一点。
首先,让我们切换到新的 Lwt 术语。根据 Lwt 库中接受的新术语,Lwt.wait
函数 returns 是一个承诺和一个解析器。
这是一个漂亮的low-level接口,通常用于实现更多high-level接口。事实上,在您的情况下,get_int
函数可以实现为 Lwt_io.read_int
。
因此,为了进行实验,让我们实现一些更有意义的东西:
let wait () =
let promise, resolver = Lwt.wait () in
Lwt.async (fun () ->
Lwt_unix.sleep (Random.float 1.0) >|=
Lwt.wakeup resolver);
promise
我们的 wait
功能 returns 一个承诺,将在随机延迟后实现。您可能会看到,有一个对 Lwt.async
的调用,它会接受一个 thunk 并在事件处理程序中异步执行它,因此会立即调用 wait
returns 函数。当然,这个例子并没有多大意义,因为具有相同语义的函数可以实现为:
let wait () = Lwt_unix.sleep 1.0
但这只是表明,wait
函数只需要实现 Lwt 原语。
当您需要分离服务提供者和服务消费者时,可以合理使用此接口。然后你可以使用Lwt.wait
(或者更好的Lwt.add_task_*
,例如
module Broker = sig
type 'a t
val request : 'a t -> 'a Lwt.t
val provide : 'a t -> 'a -> unit
end = struct
type 'a t = {mutable requested : 'a Lwt.u option}
let request broker =
let promise, request = Lwt.wait () in
broker.requested <- Some request;
promise
let provide broker data = match broker.requested with
| None -> ()
| Some request -> Lwt.wakeup request data
end
当然,我们只是重新实现了邮箱(这是另一个证明,我们通常不需要那么低,因为一切都已经为我们完成了),但一般来说,当你有多个请求时,并且你想实现你自己的调度,那么你可以使用这个 low-level 接口。
我有一个关于 lwt 的等待函数的问题,以及我如何在我自己的自定义函数中使用它,这将 return 一个 Lwt.t 线程。先给大家举个例子。
open Lwt_io
open Lwt.Infix
let i, o = Lwt_io.pipe()
let get_int () =
let t, w = Lwt.wait() in
(*what do I do here to provide the sleeping thread*)
(*with a possible integer reply*)
Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;
t
let ans = get_int()
在上面的函数中,我调用 wait 来生成一个休眠线程及其唤醒器,但我不确定如何为休眠线程提供一个可能的整数回复,并且仍然能够 return 一个休眠线程来自get_int 函数。我提供了一行 (Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;) 这似乎有效,但我不确定这是否是完成此操作的正确方法。有任何指示、链接或评论吗?
注意:我问这个问题是因为在函数中添加 Lwt_io.read_int(i) 是多余的。我可以删除 get_int 函数并调用 Lwt_io.read_int(i) 但我很好奇如果没有冗余你将如何做到这一点。
首先,让我们切换到新的 Lwt 术语。根据 Lwt 库中接受的新术语,Lwt.wait
函数 returns 是一个承诺和一个解析器。
这是一个漂亮的low-level接口,通常用于实现更多high-level接口。事实上,在您的情况下,get_int
函数可以实现为 Lwt_io.read_int
。
因此,为了进行实验,让我们实现一些更有意义的东西:
let wait () =
let promise, resolver = Lwt.wait () in
Lwt.async (fun () ->
Lwt_unix.sleep (Random.float 1.0) >|=
Lwt.wakeup resolver);
promise
我们的 wait
功能 returns 一个承诺,将在随机延迟后实现。您可能会看到,有一个对 Lwt.async
的调用,它会接受一个 thunk 并在事件处理程序中异步执行它,因此会立即调用 wait
returns 函数。当然,这个例子并没有多大意义,因为具有相同语义的函数可以实现为:
let wait () = Lwt_unix.sleep 1.0
但这只是表明,wait
函数只需要实现 Lwt 原语。
当您需要分离服务提供者和服务消费者时,可以合理使用此接口。然后你可以使用Lwt.wait
(或者更好的Lwt.add_task_*
,例如
module Broker = sig
type 'a t
val request : 'a t -> 'a Lwt.t
val provide : 'a t -> 'a -> unit
end = struct
type 'a t = {mutable requested : 'a Lwt.u option}
let request broker =
let promise, request = Lwt.wait () in
broker.requested <- Some request;
promise
let provide broker data = match broker.requested with
| None -> ()
| Some request -> Lwt.wakeup request data
end
当然,我们只是重新实现了邮箱(这是另一个证明,我们通常不需要那么低,因为一切都已经为我们完成了),但一般来说,当你有多个请求时,并且你想实现你自己的调度,那么你可以使用这个 low-level 接口。