立即杀死正在运行的未来线程

时间:2017-03-09 16:22:11

标签: clojure future cancellation

我正在使用

(def f 
   (future 
      (while (not (Thread/interrupted)) 
         (function-to-run))))

(Thread/sleep 100)
(future-cancel f)

在指定的时间(100毫秒)后取消我的代码 问题是,我需要取消已经运行的函数'function-to-run',重要的是它在100ms后真正停止执行该功能。
我可以以某种方式将中断的信号传播到函数吗? 这个功能不是第三方,我自己写的。

1 个答案:

答案 0 :(得分:7)

这里需要注意的基本事项是:没有自己的合作,你无法安全地杀死一个线程。由于您是希望能够过早杀死的功能的所有者,因此允许该功能合作并优雅安全地死亡是有意义的。

(defn function-to-run
  []
  (while work-not-done
    (if-not (Thread/interrupted)
      ; ... do your work
      (throw (InterruptedException. "Function interrupted...")))))

(def t (Thread. (fn []
                  (try
                    (while true
                      (function-to-run))
                    (catch InterruptedException e
                      (println (.getMessage e)))))))

开始线程

(.start t)

打断它:

(.interrupt t)

您的方法对于您的用例是不够的,因为仅在while返回控制流后才检查function-to-run条件,但您希望在执行期间停止function-to-run。这里的方法只是不同之处在于更频繁地检查条件,即每次通过function-to-run中的循环。请注意,您可以返回一些表示错误的值,而不是从function-to-run抛出异常,只要主线程中的循环检查此值,您就不必涉及异常。所有

如果您的function-to-run没有可以执行interrupted检查的循环,那么它可能正在执行一些阻止I / O.您可能无法中断此操作,但许多API将允许您指定操作的超时。在最坏的情况下,您仍然可以在呼叫周围的函数中对interrupted执行间歇性检查。但底线仍然适用:你不能安全地强制停止执行在函数中运行的代码;它应该合作控制。

注意: 我在这里的原始答案涉及一个使用java Thread.stop()的例子(尽管强烈反对)。根据评论中的反馈,我修改了上面的答案。