问题描述
我今天在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)))))
这篇关于备用版本的交换!也返回换出值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!