Understanding this Clojure code
我对Clojure还是很陌生,我一直在努力实现一些并发代码。我在网上找到了此代码。有一个警告,它不是在Clojure中进行并发的正确方法,但是我还是想理解这段代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | (def *readers* (map #(agent %) '("one""two""three"))) (def *writers* (map #(agent %) '("four""five"))) (def *mutex* (agent :unlocked)) (def *value* 0) ; mutex implementation (defn lock [state who success-fn fail-fn] (send who (if (= state :locked) fail-fn success-fn)) :locked) (defn unlock [mutex] :unlocked) ; Must be invoked with send-off since this handler blocks (defn rand-sleep [state next-fn] (Thread/sleep (rand-int 5)) (send *agent* next-fn) state) ; Reader functions (declare try-read) (defn reader-got-lock [name] (println (format"Thread %s says that the value is %d." name *value*)) (send *mutex* unlock) (send-off *agent* rand-sleep try-read) name) (defn reader-did-not-get-lock [name] (println (format"Thread %s tried to read the value, but could not." name)) (send-off *agent* rand-sleep try-read) name) (defn try-read [name] (send *mutex* lock *agent* reader-got-lock reader-did-not-get-lock) name) ; Writer functions (declare try-write) (defn writer-got-lock [name] (println (format"Thread %s is taking the lock." name)) (def *value* (rand-int 10)) (println (format"Thread %s is changing the value to %d." name *value*)) (send *mutex* unlock) (println (format"Thread %s is relasing the lock." name)) (send-off *agent* rand-sleep try-write) name) (defn writer-did-not-get-lock [name] (println (format"Thread %s tried to write the value, but could not." name)) (send-off *agent* rand-sleep try-write) name) (defn try-write [name] (send *mutex* lock *agent* writer-got-lock writer-did-not-get-lock) name) (dorun (map #(send % try-write) *writers*)) (dorun (map #(send % try-read) *readers*)) |
具体地说,我被困在这一行:
1 2 3 | (defn try-write [name] (send *mutex* lock *agent* writer-got-lock writer-did-not-get-lock) name) |
它应该锁定互斥锁,并根据互斥锁状态调用writer-got-lock或writer-did-not-get-lock。但是
1 | (lock @*mutex* *agent* writer-got-lock writer-did-not-get-lock) |