同步的,相互依赖的并发任务

时间:2014-06-06 08:03:14

标签: asynchronous ocaml

我搜索了一会儿,发现在Async或Lwt中没有任何明显的东西。

基本上,我有一个(长时间运行的)任务,通常会将其输出写入一个大文件,例如:

let rec foo n = if n < 0 then 0 else (store_result n ; foo (n-1))

现在我想将此计算与客户端同步。

客户端应该能够发出下一个同步点的信号,即:

let rec foo sync n = if n < 0 then 0 else (if n = sync then let sync' = store_result n in foo sync' (n-1) else foo sync (n-1))

因此store_result会将n发送给客户端,然后等待sync'。另一方面,客户端必须发送sync',然后等待相应的n

此过程应重复,直到计算完成。即客户端可以发送同步点90,50,10,9,......并在每一步获得结果。

我对异步计算有点不熟悉,但我认为有一种优雅的方式来实现整个事情。不幸的是,我无法搜索它,因为我不知道它的名字;)。

那么,解决这个问题最优雅的方法是什么?

2 个答案:

答案 0 :(得分:0)

您需要的只是简单bindreturn(如果是异步)。

基本上,我想如果你的foo到达sync,它只能在从客户端获得new sync之后继续进行,对吗?

所以async中的bind defer todo让你这样做,你说一旦延迟由异步调度程序完成,让我们计划待办事项。

open Async.Std

let store_result n = Deferred.return (n/2)

let rec foo sync n = 
  if n < 0 then Deferred.return 0 
  else 
    (if n = sync then 
    Deferred.bind (store_result n) (fun sync' -> foo sync' (n-1))
     else 
    foo sync (n-1))

我建议你阅读https://realworldocaml.org/v1/en/html/concurrent-programming-with-async.html

答案 1 :(得分:0)

以下代码与Lwt和Async同样适用。

let perform_task init n sync =
  let rec loop data n =
    let data = do_computation data in
    if n < 0 then return 0 else
    if n <> sync
    then loop data (n-1)
    else
      store_result data >>=
      fun () -> loop data (n-1) in
  loop init n

我假设,该计算是同步调用的,您需要执行n次。在同步点上,调用store_result,创建一个与thunk fun () -> loop data (n-1)绑定的延迟任务。 store_result完成后,将立即调用此thunk。

请注意,当loop变为负数时,n结束,并使用名为return的函数返回零。由于您依赖函数中的延迟计算,整个函数的结果也会延迟。

另一个注意事项:您需要open LwtAsync.Std才能访问return函数和>>=运算符。后者是bind函数的同义词。

相关问题