【问题标题】:How should I handle mutable state in Clojure in this case?在这种情况下,我应该如何处理 Clojure 中的可变状态?
【发布时间】:2016-06-22 05:31:10
【问题描述】:

总的来说,我对 Clojure 和 LISP 还很陌生,所以如果这个问题听起来有点傻,请提前原谅。我最近以 MVC 方式用 Java 创建了一个基于回合的视频游戏,其中一个线程负责图形循环(因此,以固定速率更新屏幕上图形实体的几何状态),另一个线程负责处理游戏的逻辑状态;它的行为非常像一个守护进程:除非被要求做某事(详细的用户输入),否则它在后台“休眠”,然后将“更改日志”传递给图形线程,以便它可以呈现对逻辑状态所做的更改。所以游戏世界根本没有“共享”:只有逻辑线程可以访问它,而图形线程的唯一职责是在初始化阶段之后以及当新的更改日志从逻辑线程到达时将更改应用于渲染.

我读到 Clojure 有 vars、refs 和 atom。在这种情况下,我应该使用这些身份中的哪一个来将我的游戏世界状态存储在 Clojure 的逻辑线程中?

【问题讨论】:

标签: multithreading model-view-controller clojure identity


【解决方案1】:

在您的情况下,不需要并发访问,因此任何选项都有效。

ref 是这个问题的过冲。 var 通常不会在这种情况下使用(通常 var 重新绑定用于可配置参数,而不是您的情况下的业务逻辑)。所以atom 应该没问题。

编辑:(详细说明var

var,当声明为^:dynamic(通常是*earmuffed*)时,是线程本地的。它可以有一个根绑定,每个线程都可以将它重新绑定到一个新的线程本地值。 var 的典型用法可以在 clojure 代码仓库中看到,如 *warn-on-reflection**unchecked-math* 等。它们主要以某种方式调整我们代码的行为。

由于您只有一个处理“板”数据的线程,所以 OK 无论如何都可以使用var,但对我来说看起来有点奇怪。当看到var 如此频繁地更改时,我有点不高兴。 :)

【讨论】:

  • 您好,感谢您的回复。您能否详细说明主要用于可配置参数的 vars?另外,在处理对同一资源没有并发访问的可变性时,您是否总是建议使用原子作为方法?
  • @pr0gma 我已经更新了答案。哦,对于额外的问题,我不会总是这么说。 Clojure 1.7 在引入传感器时,还引入了一个新的构造 volatile!,它是一个比 atom 更轻量级的构造,主要用于线程之间不共享的“瞬态”可变数据。
  • 我不知道易失性!构造,它看起来绝对值得询问。再次感谢您抽出宝贵时间使其更清楚!
猜你喜欢
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
相关资源
最近更新 更多