Core.async <!通道死锁
Core.async <! channel deadlock
为什么 Alpha 会提前停止,而我希望它的行为像 Beta 一样? Alpha 和 Beta 之间的唯一区别是 >!
和 put!
,如下所述。
阿尔法:
user=> (def q (chan))
#'user/q
user=> (def counter (atom 0))
#'user/counter
user=> (defn mg [event-queue]
#_=> (go-loop [event (<! event-queue)]
#_=> (swap! counter inc)
#_=> (when (< @counter 4)
#_=> (println "counter: " @counter)
#_=> (>! event-queue {:a @counter}) ;; Here's the only difference
#_=> (println "event: " event)
#_=> (recur (<! event-queue)))))
#'user/mg
user=> (mg q)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x3a1ffd56 "clojure.core.async.impl.channels.ManyToManyChannel@3a1ffd56"]
user=> (put! q "hi")
counter: true
1
user=>
测试版:
user=> (def q (chan))
#'user/q
user=> (def counter (atom 0))
#'user/counter
user=> (defn mg [event-queue]
#_=> (go-loop [event (<! event-queue)]
#_=> (swap! counter inc)
#_=> (when (< @counter 4)
#_=> (println "counter: " @counter)
#_=> (put! event-queue {:a @counter}) ;; Here's the only difference
#_=> (println "event: " event)
#_=> (recur (<! event-queue)))))
#'user/mg
user=> (mg q)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x72c9b65a "clojure.core.async.impl.channels.ManyToManyChannel@72c9b65a"]
user=> (put! q "hi")
true
counter: 1
event: hi
counter: 2
event: {:a 1}
counter: 3
event: {:a 2}
user=>
同样有趣的是,在执行 Alpha 后,通道 #'user/q
被正确排队:
user=> (take! q println)
event: hi
{:a 1}
nil
user=>
相同的结果出现在 Clojure 和 Clojurescript 中。这是某种僵局,还是假设会发生?
为什么 Alpha 会提前停止,而我希望它的行为像 Beta 一样? Alpha 和 Beta 之间的唯一区别是 >!
和 put!
,如下所述。
阿尔法:
user=> (def q (chan))
#'user/q
user=> (def counter (atom 0))
#'user/counter
user=> (defn mg [event-queue]
#_=> (go-loop [event (<! event-queue)]
#_=> (swap! counter inc)
#_=> (when (< @counter 4)
#_=> (println "counter: " @counter)
#_=> (>! event-queue {:a @counter}) ;; Here's the only difference
#_=> (println "event: " event)
#_=> (recur (<! event-queue)))))
#'user/mg
user=> (mg q)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x3a1ffd56 "clojure.core.async.impl.channels.ManyToManyChannel@3a1ffd56"]
user=> (put! q "hi")
counter: true
1
user=>
测试版:
user=> (def q (chan))
#'user/q
user=> (def counter (atom 0))
#'user/counter
user=> (defn mg [event-queue]
#_=> (go-loop [event (<! event-queue)]
#_=> (swap! counter inc)
#_=> (when (< @counter 4)
#_=> (println "counter: " @counter)
#_=> (put! event-queue {:a @counter}) ;; Here's the only difference
#_=> (println "event: " event)
#_=> (recur (<! event-queue)))))
#'user/mg
user=> (mg q)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x72c9b65a "clojure.core.async.impl.channels.ManyToManyChannel@72c9b65a"]
user=> (put! q "hi")
true
counter: 1
event: hi
counter: 2
event: {:a 1}
counter: 3
event: {:a 2}
user=>
同样有趣的是,在执行 Alpha 后,通道 #'user/q
被正确排队:
user=> (take! q println)
event: hi
{:a 1}
nil
user=>
相同的结果出现在 Clojure 和 Clojurescript 中。这是某种僵局,还是假设会发生?