【问题标题】:Why does Leiningen get stuck with a top level empty future?为什么莱宁根会陷入顶级空虚的未来?
【发布时间】:2014-06-06 18:19:04
【问题描述】:

这是一个非常简单的 Leiningen 项目示例,使用 lein new app hanging 制作,只有两个文件 project.clj

(defproject hanging "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.6.0"]]
  :main hanging.core
  :aot [hanging.core]
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

src/hanging/core.clj:

(ns hanging.core (:gen-class))

(println "1")
(def problematic (future))
(println "2")

(defn -main
    "I don't do a whole lot ... yet."
    [& args]
    (println 3)) 

运行项目时,这是输出(提示冻结,我必须用C-c杀死它):

% lein clean && lein run   
Compiling hanging.core
1
2

注释掉problematic Var 定义后,输出如下(JVM 关闭):

% lein clean && lein run
Compiling hanging.core
1
2
1
2
3

我猜 AOT 是这里的罪魁祸首,但有人能解释一下到底发生了什么吗?

我对第二个(已注释)版本没有任何问题:在 AOT 期间,编译器会执行所有顶级表单,这就是为什么 1 和 2 在输出中出现两次的原因。

但是为什么在里面添加一个空未来的 var 会改变呢?这是否意味着编译器陷入了 AOT 阶段?任何细节和指针表示赞赏...


根据建议的答案,我已将 (shutdown-agents) 添加到 (-main),但它不会更改编译步骤(编译大约需要 60 秒)。但是,有了(shutdown-agents),程序就不再挂起。

【问题讨论】:

    标签: clojure leiningen


    【解决方案1】:

    这与aot无关,更与lein无关。

    如果您添加对(shutdown-agents) 的调用,您的-main 函数将返回并且您的程序将不再挂起。 Clojure 的行为是,如果它的任何线程池工作人员可能仍然处于活动状态,则不会退出,您可以让其知道它们已完成。

    【讨论】:

    • 添加(shutdown-agents)对编译步骤没有任何作用,它仍然会挂起一段时间。它确实有助于主应用程序,它现在立即存在。我猜在 AOT 期间编译器会运行未来,然后等待它完成。
    • 是的,这是记录在案的行为。当您进行 AOT 时,命名空间中的所有顶级表单都是 evald 作为编译过程的一部分。如果您以顶级形式创建future,它将创建未来,那么您的编译过程将挂起,因为它从不调用shutdown-agents
    猜你喜欢
    • 2011-04-23
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多