I think I'm right. This is a program that demonstrates what I was thinking
o:
;; Program begins.
(defn traverse [f dat]
(vec (map #(f %) dat)))
(def data (traverse ref (take 10 (iterate inc 0))))
(-> (fn []
(dosync (loop [i 0
data data]
(when (seq data)
(Thread/sleep 1000)
(println (str ">>> " i ": " @(first data)))
(recur (+ i 1) (next data))))))
Thread.
.start)
(Thread/sleep 1500)
(dosync
(traverse (fn [ref]
(alter ref inc))
data))
(Thread/sleep 1000)
;; This one extra sleep forces the "main" thread sleeping for one
;; second. Due to some reason I don't know for now, when `dosync'
;; retries, the first sleep will be interrupted.
(Thread/sleep 1000)
(dosync
(traverse (fn [ref]
(alter ref inc))
data))
(traverse #(println (str "--- " @%)) data)
;; Program ends here.
The result is
>>> 0: 0
>>> 0: 1
--- 2
--- 3
--- 4
--- 5
--- 6
--- 7
--- 8
--- 9
--- 10
--- 11
>>> 1: 2
>>> 0: 2
>>> 1: 3
>>> 2: 4
>>> 3: 5
>>> 4: 6
>>> 5: 7
>>> 6: 8
>>> 7: 9
>>> 8: 10
>>> 9: 11
Meaning the `dosync' form in the thread is retried twice, due to the two
passes of changing of the values in `data'. So using `dosync' to surround
the whole data structure is the best way to go.
Best regards,
Guanpeng Xu
On Tue, Jan 31, 2012 at 12:00 PM, Herbert Euler <[email protected]>wrote:
> Hmm, I didn't read the definition of `board-map' carefully. It seems the
> second form
>
> (dosync (board-map deref board))
>
> is the best among the three, as it views `board' as a whole. The other
> two might have the potential problem of printing incoordinated values of
> entries in `board', i.e. the entries of `board' might change during the
> iteration in the `map' form. Am I right?
>
> Thanks,
> Guanpeng Xu
>
> On Tue, Jan 31, 2012 at 11:46 AM, Guanpeng Xu <[email protected]>wrote:
>
>> Hi all,
>>
>> In section 11.2.1 of the book /The Joy of Clojure/, the author shows
>> the effect of
>> `dosync' by starting 100 threads and then watching the value of a Ref:
>>
>> (go make-move 100 100)
>> (board-map #(dosync (deref %)) board)
>>
>> Here, the first `go' form starts 100 threads, their effect is
>> modifying `board' using
>> `dosync' and `alter'. `board-map' is defined as
>>
>> (defn board-map [f bd]
>> (vec (map #(vec (for [s %] (f s))) bd)))
>>
>> I don't quite understand the use of `dosync' in the second `board-map'
>> form. In
>> my testing, the following three seems identical:
>>
>> (board-map #(dosync (deref %) board)
>> (dosync (board-map deref board)) ;; Should be the same as above
>> (board-map deref board) ;; Without `dosync' at all
>>
>> The docstring of `deref' says "Within a transaction, returns the in-
>> transaction-value
>> of ref, else returns the most-recently-committed value of ref." So
>> the above three
>> forms are all the same, right? Or is there any difference between
>> them?
>>
>> Thanks in advance,
>> Guanpeng Xu
>
>
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en