Tom*_*ume 18 cpu profiling timeout future clojure
我有很多Java字节码的例子,我想从Clojure执行所有这些例子.每个字节码序列可能包含一个无限循环,在这种情况下,我想在几秒钟后停止运行它.我一直在期待将期货作为一种手段.在寻找几个实现后,我尝试了这两个代码:
(deref (future (loop[a 1] (recur a)) :done!) 1000 :impatient!)
Run Code Online (Sandbox Code Playgroud)
......以及https://gist.github.com/3124000上的代码
在这两种情况下,循环似乎都是适当的超时(在后一种情况下,未来报告已经完成和取消),但我看到我的CPU使用率上升到99%左右并保持在那里.我还看到每次运行此代码时,我的Java进程都会获得额外的线程.
在我看来,未来正在取消,但代码仍在运行.在我的程序中,我将需要运行和超时,一些非常紧密的无限循环(例如,相当于"20 PRINT GOTO 10"的Java字节码),我没有选择修改我正在运行的代码.
任何想法为什么我看到这种行为; 我能做些什么来阻止它; 还是替代方法让我实现运行和超时这样的代码的目标?
Java支持的线程取消机制是中断..stop()
不推荐使用该方法是有原因的 - 请参阅文档,Effective Java,Java Concurrency in Practice等.
实际上,FutureTask
(后退future-cancel
)的实现是基于中断的.
截至今天,每个Clojure的未来都由一个无界的线程池支持(就像send-off
动作一样).所以你可以利用线程中断原语:
(def worker
(let [p (promise)]
{:future (future
(let [t (Thread/currentThread)]
(deliver p t)
(while (not (Thread/interrupted))
(println 42)
(Thread/sleep 400))))
:thread @p}))
Run Code Online (Sandbox Code Playgroud)
现在可以成功执行任一(.interrupt (:thread worker))
或(future-cancel (:future worker))
.
虽然这将线程取消机制与Futures的机制相结合,但可用的Executor实现足够智能以清除先前任务可能已设置的中断状态,因此对一个任务的中断决不会影响其他任务 - 即使它们在其上运行相同的线程.
重点是先发制人地杀死线程通常是一个坏主意 - 如果你想取消任务,你必须以某种或其他方式明确地取消它们.OTOH,在您的特定情况下,您正在执行不透明的字节码,因此没有其他选择而不是诉诸.stop()
.
归档时间: |
|
查看次数: |
2099 次 |
最近记录: |