如果要花费太长时间来计算,我想打个电话
try
do_something ()
with Too_long -> something_else ()
是否可以在OCaml中执行类似的操作?该功能do_something
可能无法修改。
通常,中断功能的唯一方法是使用信号,如Basile建议的那样。不幸的是,控制流将转移到信号处理程序,因此您将无法返回所需的值。要获得更细粒度的控件,可以do_something
在单独的线程中运行。第一近似是以下函数:
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中有许多用于多处理的库,仅举几例:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句