请在2024年Clojure调查!(调查问卷)中分享您的想法!

欢迎!请参考关于页面以获取关于这个网站更多的工作信息。

+6
Clojure

我们现在遇到了这个问题很频繁,现在我们将一个Clojure系统规模扩大使用了很多Clojure之后,我猜想数字就是这样对我们"开玩笑"了,但是不管怎样这阻碍了Clojure在每一个多线程环境中的使用。我准备了一个最小示例来重现这个问题。因此,问题如下:

  • 是否有这个问题的工作方式?(就像一些我们将设置的动态变量,我没有找到,但可能存在)
  • 为什么这被认为是“沉重的打击”?(例如,require很少做,通常在单个线程环境下(例如repl),而大多数生产环境将从中受益)
  • 有什么线索能说明为什么会发生这种情况?(阅读源代码我不太理解为什么会发生这种情况,可能是由于一些ns要求(因此添加了ns),添加了所有的符号,在那里,另一个线程在要求时替换了这个ns)

1 个回答

+2

存在一个私有函数serialized-require,它在执行require操作之前简单地获得一个全局锁,您可以选择使用它,或者在您的Java代码中以clojure.core/require的任何使用处进行相同的操作,即在单个对象上的同步方法中调用所有的require调用,例如。

感谢您的回答,我知道这样做是有效的,但在我们的情况下不能使用,因为至少有一个这些类是以AOT(提前编译)的形式编写的,它反过来使用`loadWithClass`,它又调用`require`(加载`clj`文件),而我们无法控制。
如果您无法更改该AOT编译的代码,因为它真的不在您的控制范围之内,那么您是否可以评估以下代码,并在系统启动时确保它在调用多个线程从`require`之前被执行,当然,`println`是可选的。


(def original-require clojure.core/require)

(defn my-serialized-require [& args]
  (locking clojure.lang.RT/REQUIRE_LOCK
    (println "my-serialized-require acquired the lock...")
    (apply original-require args)
    (println "my-serialized-require releasing lock...")))

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


如果这也不适用于您,您是否允许编译Clojure源代码的修改版本并将其用于您的项目?如果是这样,您可以修改`require`定义以使用锁定版本。
就其价值而言,require-resolve 是对线程安全(锁定)的 require 的公共 API,我的理解是计划在某个时刻(也许是 Clojure 1.11?Alex 可能在这方面有一些见解)使用这一机制使常规 require 成为线程安全,但在将这种更改应用于 Clojure 的根本部分之前,还需要进行一些分析和可能的研究。
by
再次感谢,现在我明白问题所在,我想我可以为我们的情况实施一种变通方案。然而,这并没有解决根本问题,我非常希望看到针对此问题的长期、通用的解决方案。
by
再次感谢,现在我明白问题所在,我想我可以为我们的情况实施一种变通方案。然而,这并没有解决根本问题,我非常希望看到针对此问题的长期、通用的解决方案。
by
我理解你希望有一个长期、通用的解决方案。我是一名自愿者,回应了您询问的关于变通方案的部分。我对 Clojure 的发布版本的内容没有控制权。官方的 Clojure 维护者也会阅读这些问题,他们可以根据他们认为的长期、通用的解决方案做出回应。
by
非常感谢您的理解!
你好,只是在重复上面的事情 - 是的,这是已知问题,已纳入Clojure 1.11候选更新列表。并行(冲突)加载相对较少。`requiring-resolve`在1.10版本中添加,以解决最常见的动态加载使用场景(可能容易发生竞争)。

正如Andy提到的,clojure.lang.RT/REQUIRE_LOCK有意保留供用户程序使用,以便在该锁中参与。这应该仍被视为实现问题,并可能在未来被去除,但在此期间,可以在你提到的情况下使用建议的替代方案。

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