2024 Clojure 工作状态调查!中分享您的想法。

欢迎!请访问关于页面,了解更多关于如何使用本站的信息。

+6
Clojure

我们遇到了这个问题,因为我们重用了大量使用 Clojure 的系统,恐怕数字正在对付我们了,但不管怎样,这阻碍了 Clojure 在多线程环境中的使用。我已经编写了一个示例来重现这个问题。因此,问题是,

  • 有没有解决这个问题的解决办法?(类似于我们设置的一些动态变量,我没有找到,但可能存在)
  • 为什么这被认为是“重锤”?(例如,需要很少完成后大部分是在单线程环境下(例如,repl),而大部分生产环境则会从中受益)
  • 有什么线索能解释为什么会发生这种情况?(阅读源代码我不太理解为什么会发生这种情况,可能是因为某个ns需要(因此添加ns),并添加了所有符号,在那时,另一个线程替换了那个ns,在需要它的时候)

1 答案

+2

有一个私有函数serialized-require,它在执行require之前会获取全局锁,你可以使用它,或者在你的 Java 代码中围绕任何对clojure.core/require的使用执行相同的事情,即用全局锁包裹它,例如通过在单个对象的单个同步方法内部制作所有的require调用。

感谢您的回答,我知道这一点,但在我们的情况下 `:(` 这是不行的,因为至少有一个这些类是 AOT 编译的,这又反过来使用 `loadWithClass`,而它又调用 `require`(用于加载 `clj` 文件),这是我们不能控制的。
如果您不能更改 AOT 编译的代码,因为这真正不在您的控制之下,您是否可以评估以下所示的一些代码,并确保在从多个线程启动您的系统时在调用 `require` 之前进行评估?(startDate's are optional, of course)。


(def original-require clojure.core/require)

(defn my-serialized-require [& args]
  (locking clojure.lang.RT/REQUIRE_LOCK
    (println "my-serialized-require 获得了锁...")
    (apply original-require args)
    (println "my-serialized-require 释放锁...")))

(alter-var-root #'clojure.core/require (fn [& args] my-serialized-require))


如果这不可能,您是否允许编译 Clojure 源代码的修改版本并将其用于您的项目?如果是这样,您可以修改 `require` 的定义使其成为加锁版本。
就其意义而言,requiring-resolve 是线程安全(加锁的)require 的公共 API,我的理解是计划在某个时候(可能是 Clojure 1.11?Alex 可能对此有所见解)使常规 require 通过这种机制线程安全,但在对 Clojure 的基本部分进行此类更改之前,还需要进行一些分析和可能的研究。
再次感谢,现在我确实理解了问题所在,我认为我可以为我们的情况制定一个补救方案。然而,这并没有解决问题根源,我希望看到对此的长期、一般性的解决方案。
by
再次感谢,现在我确实理解了问题所在,我认为我可以为我们的情况制定一个补救方案(调试技巧)。然而,这并没有解决问题根源,我希望看到对此的长期、一般性的解决方案。
by
我理解您对长期一般性解决方案的渴望。我是一个感兴趣的志愿者,在您询问补救方案的地方回应您。我无法控制Clojure发布版本的内容。官方Clojure维护者也会阅读这些问题,并可以提供他们认为的长期一般性解决方案。
by
十分感谢您的理解和帮助!
by
您好,我只是重复上面的话——是的,这确实是一个已知问题,已经添加到Clojure 1.11的候选列表中。并行(冲突)的加载相对较少。`requiring-resolve`是在1.10中添加的,用于覆盖最常见的动态加载用例(这很容易发生冲突)。

正如Andy前面提到的,clojure.lang.RT/REQUIRE_LOCK 故意保留可用,以便需要参与此锁的用户程序可以做到这一点。这仍然应被视为实现细节,并可能在未来被移除,但在此期间,您提到的此类情况可以使用建议的解决方案。

预期长期解决方案是使正常的 `require` 更安全,但这将需要大量的分析和测试,而这些测试尚未完成。
by
gen-class 也可能是一个常见的用例。如果您从 Clojure 生成一个类,而 Java 在多个线程中创建该类的实例,则生成的类初始化器很可能在后台以一种非线程安全的方式,需要实现该 Clojure 名称空间。我们 目前似乎存在此问题。
...