使用 Clojure(和其他 Lisp 方言),您可以修改正在运行的代码。那么,在运行时修改函数时,该更改是否可用于多个线程?
我试图弄清楚它在并发设置中的技术工作原理:如果多个线程正在使用函数foo,当我重新定义(比如使用defn)函数foo时会发生什么?
必须进行一些同步:这种同步何时以及如何发生以及它的成本是多少?
比如说在 JVM 上,函数是使用引用来引用的volatile
吗?如果是这样,这是否意味着每次都有“函数查找”,那么就必须付出volatile
代价?
使用 Clojure(和其他 Lisp 方言),您可以修改正在运行的代码。那么,在运行时修改函数时,该更改是否可用于多个线程?
我试图弄清楚它在并发设置中的技术工作原理:如果多个线程正在使用函数foo,当我重新定义(比如使用defn)函数foo时会发生什么?
必须进行一些同步:这种同步何时以及如何发生以及它的成本是多少?
比如说在 JVM 上,函数是使用引用来引用的volatile
吗?如果是这样,这是否意味着每次都有“函数查找”,那么就必须付出volatile
代价?
在 Clojure 中,函数是IFn
类的实例,它们几乎总是存储在vars
. vars 是线程局部值的 Clojures 机制。
binding
which 会给出它们自己的线程本地值,它们可以随意更改,因为没有其他线程可以读取它。对 vars 的深入了解非常值得研究一下,一旦你习惯了它们,它们就是一个非常有用的并发设备。
ps:根线程通常是 REPL pss:你当然可以自由地将你的函数存储在 vars 以外的东西中,例如,如果你需要原子地更新一组函数,尽管这种情况很少见。