在一个时间限制内执行函数的惯用方法是什么?就像是,
(with-timeout 5000
(do-somthing))
Run Code Online (Sandbox Code Playgroud)
除非do-something返回5000以内抛出异常或返回nil.
编辑:在有人指出它之前,
clojure(with-timeout ... macro)
但随着这一点,未来继续执行,在我的情况下不起作用.
mik*_*era 17
我认为你可以通过在期货中使用超时功能来合理可靠地做到这一点:
(defmacro with-timeout [millis & body]
`(let [future# (future ~@body)]
(try
(.get future# ~millis java.util.concurrent.TimeUnit/MILLISECONDS)
(catch java.util.concurrent.TimeoutException x#
(do
(future-cancel future#)
nil)))))
Run Code Online (Sandbox Code Playgroud)
一些实验验证你需要做一个future-cancel来阻止未来的线程继续执行....
ama*_*loy 13
这不是你可以在JVM上100%可靠地完成的事情.一段时间后停止某事的唯一方法是给它一个新线程,然后在你希望它停止时发送该线程异常.但是他们的代码可以捕获异常,或者他们可以启动另一个你无法控制的线程,或者......
但大部分时间,特别是如果你控制正在超时的代码,你可以像在clojail中那样做:
如果你想做得更漂亮,你可以定义一个宏
(defmacro with-timeout [time & body]
`(thunk-timeout (fn [] ~@body) ~time))
Run Code Online (Sandbox Code Playgroud)
Jer*_*ijk 10
关于什么?
(defn timeout [timeout-ms callback]
(let [fut (future (callback))
ret (deref fut timeout-ms ::timed-out)]
(when (= ret ::timed-out)
(future-cancel fut))
ret))
(timeout 100 #(Thread/sleep 1000))
;=> :user/timed-out
Run Code Online (Sandbox Code Playgroud)
小智 6
使用 Clojure 的通道设施轻而易举 https://github.com/clojure/core.async
需要各自的命名空间
(:require [clojure.core.async :refer [>! alts!! timeout chan go]])
Run Code Online (Sandbox Code Playgroud)
函数 wait 需要超时 [ms]、函数 [f] 和可选参数 [args]
(defn wait [ms f & args]
(let [c (chan)]
(go (>! c (apply f args)))
(first (alts!! [c (timeout ms)]))))
Run Code Online (Sandbox Code Playgroud)
第三行将对 f 的调用弹出到另一个线程。第四行消耗函数调用的结果或(如果更快)超时。
考虑以下示例调用
(wait 1000 (fn [] (do (Thread/sleep 100) 2)))
=> 2
Run Code Online (Sandbox Code Playgroud)
但
(wait 50 (fn [] (do (Thread/sleep 100) 2)))
=> nil
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4631 次 |
最近记录: |