中断OCaml中的通话 [英] Interrupt a call in OCaml

查看:80
本文介绍了中断OCaml中的通话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果计算时间太长,我想打个电话

I'd like to interrupt a call if it takes too long to compute, like this

try
   do_something ()
with Too_long -> something_else ()

是否可以在OCaml中执行类似的操作?函数do_something可能无法修改.

Is it possible to do something like that in OCaml? The function do_something may not be modified.

推荐答案

通常,中断功能的唯一方法是使用信号,如Basile建议的那样.不幸的是,控制流将被转移到信号处理程序,因此您将无法返回所需的值.要获得更细粒度的控件,可以在单独的线程中运行do_something.一阶近似应为以下函数:

In general the only way to interrupt a function is to use a signal, as Basile suggested. Unfortunately the control flow will be transferred to a signal handler, so that you will be unable to return a value that you like. To get a more fine-grained control, you can run you do_something in separate thread. A first approximation would be the following function:

exception Timeout

let with_timeout timeout f =
  let result = ref None in
  let finished = Condition.create () in
  let guard = Mutex.create () in
  let set x =
    Mutex.lock guard;
    result := Some x;
    Mutex.unlock guard in
  Mutex.lock guard;
  let work () =
    let x = f () in
    set x;
    Condition.signal finished in
  let delay () =
    Thread.delay timeout;
    Condition.signal finished in
  let task = Thread.create work () in
  let wait = Thread.create delay () in
  Condition.wait finished guard;
  match !result with
  | None ->
    Thread.kill task;
    raise Timeout
  | Some x ->
    Thread.kill wait;
    x

带有线程以及带有信号功能的解决方案有一些缺点.例如,在OCaml中的特定迭代点上切换线程,通常这是任何分配.因此,如果您的代码不执行任何分配或外部调用,则它可能永远不会屈服于其他线程,并且将永远运行.此类功能的一个很好的例子是let rec f () = f ().在这种情况下,您应该在另一个进程而不是线程中运行函数.在OCaml中有许多用于多处理的库,仅举几例:

The solution with threads as well as with signal function has some drawbacks. For example, threads are switched in OCaml in specific iterruption points, in general this is any allocations. So if your code doesn't perform any allocations or external calls, then it may never yield to other thread and will run forever. A good example of such function is let rec f () = f (). In this is your case, then you should run your function in another process instead of thread. There're many libraries for multiprocessing in OCaml, to name a few:

  1. parmap
  2. 叉车
  3. 异步并行
  4. lwt-parallel
  1. parmap
  2. forkwork
  3. async-parallel
  4. lwt-parallel

这篇关于中断OCaml中的通话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆