【问题标题】:Immediately kill a running future thread立即终止正在运行的未来线程
【发布时间】:2017-07-30 17:41:24
【问题描述】:

我正在使用

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

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

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

【问题讨论】:

  • 我完全修改了我的答案,可能想看看它是否适用于您的用例。
  • 对我来说,运行代理而不是未来对您的用例来说似乎要好得多。 IE。如果应该发出代理的下一次迭代,您可以控制一个原子:(if @running (send *agent* nil))(因此您甚至不需要while 循环)。您可以在运行的函数中随时检查原子的状态,并在必要时提前返回。 (参见 Rich Hickey 著名的 ants.clj 示例。)

标签: clojure future cancellation


【解决方案1】:

这里要注意的基本事项是:如果没有线程自身的合作,您无法安全地杀死线程。由于您是您希望能够过早终止的函数的所有者,因此允许该函数合作并优雅而安全地终止是有意义的。

(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)

您的方法不足以满足您的用例,因为仅在从function-to-run 返回控制流之后才检查while 条件,但您想在其执行期间停止function-to-run。这里的方法只是不同之处在于更频繁地检查条件,即每次通过function-to-run中的循环。请注意,除了从function-to-run 抛出异常之外,您还可以返回一些指示错误的值,并且只要您在主线程中的循环检查该值,您根本不必涉及异常。

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

注意: 我在这里的原始答案涉及展示一个使用 java 的 Thread.stop() 的示例(尽管强烈建议不要这样做)。根据 cmet 的反馈,我修改了上面的答案。

【讨论】:

  • 谢谢,这就是我想要的。它的终止要早得多,但似乎还没有立即终止。不能立即杀死吗?反正比以前好多了。
  • Thread/stopjavadoc 中标有巨大的生物危害/放射性/死亡标志。不仅难以安全使用,而且不可能安全使用,千万不要使用它。弃用通知附带了您应该做什么的描述,并且确实是此处提出的问题的完美解决方案。
  • 你不应该使用 Thread.stop()。可以改用 Thread.interrupt()。您可以在函数中捕获并处理 InterruptedException。如果您实际上阻塞了 I/O 操作,这可能有效也可能无效(阅读操作文档),您应该考虑其他选项。
  • @AlexMiller 更新了答案;我知道我什至不应该提到这种方法,因为我自己从来不会使用它。感谢您的反馈
  • @amalloy 更新了答案;我知道我什至不应该提到这种方法,因为我自己从来不会使用它。感谢您的反馈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
  • 2022-11-21
  • 2018-11-11
  • 1970-01-01
相关资源
最近更新 更多