本文介绍了备用版本的交换!也返回换出值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天在IRC的 #clojure 频道上说了一下,但想在这里详细讨论。基本上,为了更好地理解原子, swap! deref 和Clojure并发作为一个整体,我想尝试写一个函数,它不仅返回使用 swap!交换的值,而且返回被换出的值。

I talked about this a bit on IRC's #clojure channel today but would like to go more in detail here. Basically, in order to better understand atoms, swap!, deref and Clojure concurrency as a whole, I'd like to try to write a function which not only returns the value that was swapped-in using swap!, but also the value that was swapped out.

(def foo (atom 42))

.
.
.

((fn [a]
  (do
    (println "swapped out: " @a)
    (println "swapped in: "(swap! a rand-int)))) foo)

可以打印:

swapped out:  42
swapped in:   14

但是,如果另一个线程 @a 之间有相同的原子 swap! > deref ,并调用 swap!,那么我可能会换出不是42的值。

However if another thread does swap! the same atom between the @a deref and the call to swap! then I may be swapping out a value that is not 42.

我如何写一个函数来正确地给出两个值(换出和换入)?

How can I write a function which gives back correctly both values (the swapped out and the swapped in)?

我不在乎各种值,原子确实改变为:我想知道的是什么值换出。

I don't care about the various values that the atom does change to: all I want to know is what was the value swapped out.

这可以使用代码保证不会死锁和如果是为什么?

Can this be written using code that is guaranteed not to deadlock and if so why?

推荐答案

Clojure的 swap! - 设置。您可以定义一个替换版本,返回您喜欢的任何内容:

Clojure's swap! is just a spinning compare-and-set. You can define an alternate version that returns whatever you like:

(defn alternate-swap [atom f & args]
  (loop []
    (let [old @atom
          new (apply f old args)]
      (if (compare-and-set! atom old new)
        [old new]  ; return value
        (recur)))))

这篇关于备用版本的交换!也返回换出值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 14:43