【问题标题】:Clojure dosync inside future vs future inside dosync未来内部的 Clojure dosync 与 dosync 内部的未来
【发布时间】:2017-11-07 16:00:53
【问题描述】:

我有以下代码

(def number (ref 0))

(dosync (future (alter number inc)))  ; A
(future (dosync (alter number inc)))  ; B

第二个成功,但第一个失败,no transaction is running。但它被包裹在一个 dosync 中,对吧?

clojure 是否记得根据在哪个线程中创建事务来打开事务?

【问题讨论】:

    标签: clojure stm


    【解决方案1】:

    你是对的。 dosync 的全部目的是在当前线程中开始一个事务。 future 在新线程中运行它的代码,所以 alter 以防 A 不在其线程的 dosync 内。

    对于案例 B,alterdosync 都在同一个(新)线程中,所以没有问题。

    【讨论】:

      【解决方案2】:

      这不起作用有多种原因。正如 Alan Thompson 所写,事务驻留在单个线程中,因此当您创建新线程时,您会丢失事务。

      另一个问题是dosync 的动态范围。如果你写了同样的问题会出现

      ((dosync #(alter number inc)))
      

      这里我们在dosync 范围内创建一个函数,并让该函数成为dosync 的结果。然后我们从dosync 块外部调用该函数,当然事务不再运行。

      这与您对future 所做的非常相似:future 创建一个函数,然后在新线程上执行它,返回一个句柄,您可以使用该句柄检查该线程的进度。即使允许跨线程事务,这里也会出现竞争条件:dosync 块是在执行 future 中的 alter 调用之前还是之后关闭其事务?

      【讨论】:

        猜你喜欢
        • 2011-04-04
        • 2016-11-07
        • 1970-01-01
        • 1970-01-01
        • 2022-11-27
        • 1970-01-01
        • 2021-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多