使用 Clojure(和其他 Lisp 方言),您可以修改正在运行的代码。那么,当在运行时修改函数时,该更改是否可供多个线程使用?
我试图弄清楚它在并发设置中在技术上是如何工作的:如果多个线程正在使用一个函数foo,当我重新定义时会发生什么(比如使用defn>) 函数 foo?
必须进行一些同步:这种同步何时以及如何发生以及它的成本是多少?
假设在 JVM 上,函数是使用 volatile
引用来引用的吗?如果是这样,是否意味着每次进行“函数查找”时都必须支付 volatile
成本?
最佳答案
在 Clojure 中,函数是 IFn 类的实例,它们 are almost always stored in vars
。 vars 是用于线程本地值的 Clojures 机制。
- 当您定义一个函数并将 var 的“根绑定(bind)”设置为引用该函数时
- 线程其他线程获取 var 根绑定(bind)的当前值,但无法更改该值。这可以防止任何两个线程争夺 var 的值,因为只有根线程可以设置该值。
- 如果需要,线程可以选择使用 var 的新值,但调用
binding
会给出它们自己的线程本地值,并且可以自由更改随意,因为没有其他线程可以读取它。
对变量的充分理解是值得花点时间研究的,一旦你习惯了它们,它们就是一个非常有用的并发设备。
ps:根线程通常是REPL pss:当然,如果您需要原子地更新一组函数,您当然可以将函数存储在 var 之外的其他位置,尽管这种情况很少见。
关于function - 函数如何在运行时修改然后传播到多个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11236542/